我已经编写了一些用于Jenkins管道的常规实用程序方法。一个简单的例子是:
// src/org/package/utils.groovy
def remove_file(String file) {
new File(file).delete()
}
但是,正如预期的那样,这会在Jenkins管道中抛出以下异常:
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException:脚本不允许使用新的java.io.File java.lang.String
根据Script Security Plugin documentation,我可以使用@Whitelisted
方法注释绕过这个:
@Whitelisted
def remove_file(String file) {
new File(file).delete()
}
根据这个question,我可以使用@NonCPS
注释绕过这个(当然,此方法中的代码无需进行序列化):
@NonCPS
def remove_file(String file) {
new File(file).delete()
}
共享库正在全局变量中使用,如下所示:
// vars/var.groovy
import org.package.utils
def method(body) {
...
new utils().remove_file('file')
...
}
正在导入库/ var并在Jenkins文件中使用,如下所示:
library identifier: 'lib@master', retriever: modernSCM(
[$class: 'GitSCMSource',
remote: 'https://github.com/org/repo.git'])
pipeline {
...
script {
var.method {
// body
}
}
...
}
在列出的基于代码的导入Pipeline共享库的方法中,我上面使用的方法似乎是唯一一个实际使用标准Jenkins Pipeline插件集的方法,所以这就是我采用的方法。
这两个都未能绕过Jenkins Pipeline抛出的安全异常。什么是使用代码绕过脚本安全插件并避免手动/人为错误解决方案(如修改GUI中的白名单)的最佳解决方案?
答案 0 :(得分:4)
根据您上次发表的评论以及您对原始问题的更新,我想我了解情况。我将尝试澄清全球共享图书馆和"常规图书馆之间的差异。共享库。
在撰写本文时,有一些不同的方法可以向Jenkins实例注册共享库。
Folder
- 文件夹中的所有项目都有可用的管道库图书馆注册需要一些设置:
library
步骤和@Library
注释一起使用的库名称@Library
或library
)上面引用的Global Shared Libraries会绕过安全沙箱,这意味着他们可以执行任何。以下是一些相关的documentation:
由于这些库可以全局使用,因此系统中的任何管道都可以利用这些库中实现的功能。
这些图书馆被视为"信任:"他们可以在Java,Groovy,Jenkins内部API,Jenkins插件或第三方库中运行任何方法。这允许您定义库,这些库将单独的不安全API封装在更高级别的包装器中,以便从任何管道中使用。请注意任何能够推送到此SCM存储库的人都可以无限制地访问Jenkins。您需要
Overall/RunScripts
权限才能配置这些库(通常这将授予Jenkins管理员)。 / p>
这些是唯一绕过安全沙箱检查的管道库。其他类型(如文件夹库)已进行安全检查,这意味着您无法执行new File(file).delete()
之类的操作。
在管道中,用户可以访问所有可用的共享库。安装或文件夹中隐式加载的库(以上称为 Load implicitly 选项)在脚本类路径中自动可用。必须使用@Library
注释或library
步骤引入其他库。
例如,假设您有一个包含以下选项的库:
my-shared-lib
master
false
true
您可以从管道中获取此特定库的几种方法是:
@Library('my-shared-lib')
- 使用默认版本@Library('my-shared-lib@develop')
- 使用已覆盖的develop
def myLib = library('my-shared-lib@develop')
- 使用已覆盖的develop
这些都将使用先前配置的库。
在您的示例中,您使用的是library
步骤,但是从远程存储库动态加载而不是使用注册版本。这也是您指定retriever
参数的原因。请记住,任何非全局共享库 的库都无法绕过安全沙箱。
如果您想让您的库绕过沙箱,您需要将其作为全局共享库以Jenkins安装注册。
关于new File(file).delete()
的附注 - 小心写作"正常" Jenkins管道内部的Groovy(有关详细原因,请参阅此answer。)
答案 1 :(得分:0)
如果您使用Jenkins Job-DSL以编程方式创建作业,则可以使用以下代码自动批准管道脚本。
def pipelineScript = 'your pipeline script'
def scriptApproval = Jenkins.instance.getExtensionList('org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval')[0]
scriptApproval.approveScript(scriptApproval.hash(pipelineScript, 'groovy'))
script pipelineScript
此代码可能需要一些调整,具体取决于您使用的插件的版本,否则这应该会使事情变得更容易。
和平!