java - 如何在文件夹级别读取 Jenkins 凭据

标签 java jenkins jenkins-pipeline jenkins-plugins jenkins-groovy

我正在尝试将凭据从 Jenkins 迁移到另一个凭据存储。

我想从 Jenkins 商店读取凭据,并找到了这个脚本 ( https://github.com/tkrzeminski/jenkins-groovy-scripts/blob/master/show-all-credentials.groovy

该脚本对 的 SystemCredentialsProvider 凭据执行正常根级别的全局域 .

但是我的凭据存储在文件夹中 ,所以该脚本对我不起作用。

我正在使用 Jenkins 脚本控制台来执行脚本。

如果我导航到 Jenkins 凭据配置页面并将鼠标悬停在我的凭据条目之一的图标上,工具提示会显示“文件夹凭据提供程序”。

================================================== ==

问题:如何从 Jenkins 的文件夹中读取所有凭据?

================================================== ==

请参阅下面的脚本:

import jenkins.model.*
import com.cloudbees.plugins.credentials.*
import com.cloudbees.plugins.credentials.impl.*
import com.cloudbees.plugins.credentials.domains.*
import com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey
import com.cloudbees.jenkins.plugins.awscredentials.AWSCredentialsImpl
import org.jenkinsci.plugins.plaincredentials.StringCredentials
import org.jenkinsci.plugins.plaincredentials.impl.FileCredentialsImpl

def showRow = { credentialType, secretId, username = null, password = null, description = null ->
  println("${credentialType} : ".padLeft(20) + secretId?.padRight(38)+" | " +username?.padRight(20)+" | " +password?.padRight(40) + " | " +description)
}

// set Credentials domain name (null means is it global)
domainName = null

credentialsStore = Jenkins.instance.getExtensionList('com.cloudbees.plugins.credentials.SystemCredentialsProvider')[0]?.getStore()
domain = new Domain(domainName, null, Collections.<DomainSpecification>emptyList())

credentialsStore?.getCredentials(domain).each{
  if(it instanceof UsernamePasswordCredentialsImpl)
    showRow("user/password", it.id, it.username, it.password?.getPlainText(), it.description)
  else if(it instanceof BasicSSHUserPrivateKey)
    showRow("ssh priv key", it.id, it.passphrase?.getPlainText(), it.privateKeySource?.getPrivateKey(), it.description)
  else if(it instanceof AWSCredentialsImpl)
    showRow("aws", it.id, it.accessKey, it.secretKey?.getPlainText(), it.description)
  else if(it instanceof StringCredentials)
    showRow("secret text", it.id, it.secret?.getPlainText(), '', it.description)
  else if(it instanceof FileCredentialsImpl)
    showRow("secret file", it.id, it.content?.text, '', it.description)
  else
    showRow("something else", it.id, '', '', '')
}

return

最佳答案

@Shaybc 共享的类是大部分解决方案,尽管评论者认为它本身并不是一个完整的解决方案,但我能够猜测如何在我自己的 Groovy 脚本中将它正确地实现为这样一个完整的解决方案。

JenkinsCredentials.getFolderItem('foldername') 返回的文件夹采用与 Jenkins 中您的文件夹相同的字符串。因此,如果您有一个具有描述性名称的文件夹和一个 slug,例如“文件夹名称”和“文件夹名称”,那么用于检索文件夹本身的正确字符串是“文件夹名称”。

示例 provided here 显示了如何从全局存储中检索凭据,这是 Jenkins.instance - 对于完整的文档,他们提供的脚本复制到此处:

import jenkins.*
import jenkins.model.* 
import hudson.*
import hudson.model.*
def jenkinsCredentials = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
        com.cloudbees.plugins.credentials.Credentials.class,
        Jenkins.instance,
        null,
        null
);
for (creds in jenkinsCredentials) {
    println(jenkinsCredentials.id)
    }

因此,通过将 class JenkinsCredentials 定义为@Shaybc 描述来启动脚本,然后不要使用 CredentialsProvider.lookupCredentials 调用 Jenkins.instance ,而是检索文件夹并将其传递到那里。

我的文件夹被称为“ft”并且(跳过顶部的导入/样板和 JenkinsCredentials 帮助程序类的定义)我在 Groovy 脚本中调用的其余部分如下所示:
def folder = JenkinsCredentials.getFolderItem('ft');

def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
        com.cloudbees.plugins.credentials.Credentials.class,
        folder,
        null,
        null
);
for (c in creds) {
    println(c.id + ": " + c.description)
}

希望这对某人有所帮助!顺便说一句,如果您的凭据存储在文件中而不是字符串中,您还有一步……该文件在“描述”属性中将没有任何有用的内容,您需要存储在 c.getContent() 的字节流

因此,最后一个带有一些元编程的循环来动态检查要调用的 getContent() 方法的可用性:
for (c in creds) {
 if (c.metaClass.respondsTo(c, 'getContent')) {
  println(
   IOUtils.toString(c.getContent(), StandardCharsets.UTF_8)
  )
 }
 println(c.id + ": " + c.description)
}

最后一部分是从这个答案中借用的,它还显示了如何导入 StandardCharsets 和 IOUtils:https://stackoverflow.com/a/42360792/661659

关于java - 如何在文件夹级别读取 Jenkins 凭据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57107486/

相关文章:

java - 向多个客户发布问题

groovy - 当模板名称是变量时如何使用 Groovy 模板引擎?

jenkins - 寻找 Jenkins 插件以允许每个分支的默认参数值

java - ClassCastException : java. math.BigInteger 在连接到 MySQL 时无法转换为 java.lang.Long

java - 为什么这会抛出 IllegalMonitorStateException?

java - Jenkins:删除旧构建

jenkins - 如何将管道中的 bool 参数值传递给下游作业?

git - 从声明式 Jenkins 管道中的私有(private) Git 存储库下载单个文件

java - PostgreSQL 错误,类型 Java_Object 不存在

jenkins - Jenkins 的 Docker 插件错误 : Scripts not permitted to use method