Inspired by Jesse's
example DSL using docker workflow, I thought I would see how far I could take things in making DSLs.
I wanted to make things that looked very similar to what people do with tools like travis - something at home in a Jenkinsfile that anyone can open, and read and immediately comprehend, for simple cases, what the build instructions are.
It can work with or without docker workflow (you just specify an image, or not), sends emails (even in failure), set environment variables etc, of course I would love for it to do more.
However, one road block has been my use of literal maps and the sandbox. This all works grand if I don't use the sandbox, but use the sandbox (or multibranch/SCM, which enables sandbox), and sadness results that I can't work out how to get around:
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use field java.util.HashMap$Node key
at org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.StaticWhitelist.rejectField(StaticWhitelist.java:169)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.rejectField(SandboxInterceptor.java:195)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:
- this shows up when I enable the sandbox (sadbox?).
It seems NOTHING in java.util.Map is whitelisted. I am using maps at the moment as it makes for a nice DSL similar to what people may see elsewhere. For example:
simpleBuild {
script = 'echo after $FOO'
notifications = [
]
env = [
FOO = "well hello",
BAR = "I don't even need to be here"
]
}
This is valid and works great *without* sandbox, but fails on notifications with sandbox on. The notifications item (config.notifications in the DSL, from the closure passed into simpleBuild) is a java.util.Map. If I look closer, its actually a LinkedHashMap.
Does any one have ideas on ways to get around this? the literal map notation is very neat, and would take no time for someone to glance at and follow, however, I don't see a way of working with a Map (I can call size() it seems, but nothing else, I can't get the values() or keySet() collections etc).
Any ideas appreciated (perhaps using maps is inferior to another approach, which I would like to see, however, I love the idea of staying in pipieline-groovy script, with a DSL, as this takes away NONE of the power).