Files
ma/k8s-dvfs/src/main/groovy/recreationaltech/plugin/model/PodOptions.groovy

324 lines
10 KiB
Groovy

/*
* Copyright 2013-2026, Seqera Labs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package recreationaltech.plugin.model
import groovy.transform.CompileStatic
import groovy.transform.EqualsAndHashCode
import groovy.transform.PackageScope
import groovy.transform.ToString
/**
* Model K8s pod options such as environment variables,
* secret and config-maps
*
* @author Paolo Di Tommaso <paolo.ditommaso@gmail.com>
*/
@CompileStatic
@ToString(includeNames = true)
@EqualsAndHashCode(includeFields = true)
class PodOptions {
private String imagePullPolicy
private String imagePullSecret
private Collection<PodEnv> envVars
private Collection<PodMountConfig> mountConfigMaps
private Collection<PodMountCsiEphemeral> mountCsiEphemerals
private Collection<PodMountEmptyDir> mountEmptyDirs
private Collection<PodMountSecret> mountSecrets
private Collection<PodVolumeClaim> mountClaims
private Collection<PodHostMount> mountHostPaths
private Map<String,String> labels = [:]
private Map<String,String> annotations = [:]
private PodNodeSelector nodeSelector
private Map affinity
private PodSecurityContext securityContext
private boolean automountServiceAccountToken
private String priorityClassName
private List<Map> tolerations
private Boolean privileged
private String schedulerName
private Integer ttlSecondsAfterFinished
private String runtimeClassName
PodOptions( List<Map> options=null ) {
int size = options ? options.size() : 0
envVars = new HashSet<>(size)
mountConfigMaps = new HashSet<>(size)
mountCsiEphemerals = new HashSet<>(size)
mountEmptyDirs = new HashSet<>(size)
mountSecrets = new HashSet<>(size)
mountClaims = new HashSet<>(size)
mountHostPaths = new HashSet<>(10)
automountServiceAccountToken = true
tolerations = new ArrayList<Map>(size)
init(options)
}
@PackageScope void init(List<Map> options) {
if( !options ) return
for( Map entry : options ) {
create(entry)
}
}
@PackageScope void create(Map<String,String> entry) {
if( entry.env && entry.value ) {
envVars << PodEnv.value(entry.env, entry.value)
}
else if( entry.env && entry.fieldPath ) {
envVars << PodEnv.fieldPath(entry.env, entry.fieldPath)
}
else if( entry.env && entry.secret ) {
envVars << PodEnv.secret(entry.env, entry.secret)
}
else if( entry.env && entry.config ) {
envVars << PodEnv.config(entry.env, entry.config)
}
else if( entry.mountPath && entry.secret ) {
mountSecrets << new PodMountSecret(entry)
}
else if( entry.mountPath && entry.config ) {
mountConfigMaps << new PodMountConfig(entry)
}
else if( entry.mountPath && entry.csi ) {
mountCsiEphemerals << new PodMountCsiEphemeral(entry)
}
else if( entry.mountPath && entry.emptyDir != null ) {
mountEmptyDirs << new PodMountEmptyDir(entry)
}
else if( entry.mountPath && entry.volumeClaim ) {
mountClaims << new PodVolumeClaim(entry)
}
else if( entry.mountPath && entry.hostPath instanceof CharSequence ) {
mountHostPaths << new PodHostMount(entry.hostPath, entry.mountPath)
}
else if( entry.pullPolicy || entry.imagePullPolicy ) {
this.imagePullPolicy = entry.pullPolicy ?: entry.imagePullPolicy as String
}
else if( entry.imagePullSecret || entry.imagePullSecrets ) {
this.imagePullSecret = entry.imagePullSecret ?: entry.imagePullSecrets
}
else if( entry.label && entry.value ) {
this.labels.put(entry.label as String, entry.value as String)
}
else if( entry.runAsUser != null ) {
this.securityContext = new PodSecurityContext(entry.runAsUser)
}
else if( entry.securityContext instanceof Map ) {
this.securityContext = new PodSecurityContext(entry.securityContext as Map)
}
else if( entry.nodeSelector ) {
this.nodeSelector = new PodNodeSelector(entry.nodeSelector)
}
else if( entry.affinity instanceof Map ) {
this.affinity = entry.affinity as Map
}
else if( entry.annotation && entry.value ) {
this.annotations.put(entry.annotation as String, entry.value as String)
}
else if( entry.automountServiceAccountToken instanceof Boolean ) {
this.automountServiceAccountToken = entry.automountServiceAccountToken as Boolean
}
else if( entry.priorityClassName ) {
this.priorityClassName = entry.priorityClassName
}
else if( entry.toleration instanceof Map ) {
tolerations << (entry.toleration as Map)
}
else if( entry.privileged instanceof Boolean ) {
this.privileged = entry.privileged as Boolean
}
else if( entry.schedulerName ) {
this.schedulerName = entry.schedulerName
}
else if( entry.ttlSecondsAfterFinished instanceof Integer ) {
this.ttlSecondsAfterFinished = entry.ttlSecondsAfterFinished as Integer
}
else if( entry.runtimeClassName ) {
this.runtimeClassName = entry.runtimeClassName
}
else
throw new IllegalArgumentException("Unknown pod options: $entry")
}
Collection<PodEnv> getEnvVars() { envVars }
Collection<PodMountConfig> getMountConfigMaps() { mountConfigMaps }
Collection<PodMountCsiEphemeral> getMountCsiEphemerals() { mountCsiEphemerals }
Collection<PodMountEmptyDir> getMountEmptyDirs() { mountEmptyDirs }
Collection<PodMountSecret> getMountSecrets() { mountSecrets }
Collection<PodHostMount> getMountHostPaths() { mountHostPaths }
Collection<PodVolumeClaim> getVolumeClaims() { mountClaims }
Map<String,String> getLabels() { labels }
Map<String,String> getAnnotations() { annotations }
PodNodeSelector getNodeSelector() { nodeSelector }
PodOptions setNodeSelector( PodNodeSelector sel ) {
nodeSelector = sel
return this
}
Map getAffinity() { affinity }
PodSecurityContext getSecurityContext() { securityContext }
PodOptions setSecurityContext( PodSecurityContext ctx ) {
this.securityContext = ctx
return this
}
String getImagePullSecret() { imagePullSecret }
PodOptions setImagePullSecret( String secret ) {
this.imagePullSecret = secret
return this
}
String getImagePullPolicy() { imagePullPolicy }
PodOptions setImagePullPolicy( String policy ) {
this.imagePullPolicy = policy
return this
}
boolean getAutomountServiceAccountToken() { automountServiceAccountToken }
PodOptions setAutomountServiceAccountToken( boolean mount ) {
this.automountServiceAccountToken = mount
return this
}
String getPriorityClassName() { priorityClassName }
String getSchedulerName() { schedulerName }
List<Map> getTolerations() { tolerations }
Boolean getPrivileged() { privileged }
Integer getTtlSecondsAfterFinished() { ttlSecondsAfterFinished }
String getRuntimeClassName() { runtimeClassName }
PodOptions plus( PodOptions other ) {
def result = new PodOptions()
// env vars
result.envVars.addAll(envVars)
result.envVars.addAll( other.envVars )
// config maps
result.mountConfigMaps.addAll( mountConfigMaps )
result.mountConfigMaps.addAll( other.mountConfigMaps )
// csi ephemeral volumes
result.mountCsiEphemerals.addAll( mountCsiEphemerals )
result.mountCsiEphemerals.addAll( other.mountCsiEphemerals )
// empty dirs
result.mountEmptyDirs.addAll( mountEmptyDirs )
result.mountEmptyDirs.addAll( other.mountEmptyDirs )
// host paths
result.mountHostPaths.addAll( mountHostPaths )
result.mountHostPaths.addAll( other.mountHostPaths )
// secrets
result.mountSecrets.addAll( mountSecrets )
result.mountSecrets.addAll( other.mountSecrets )
// volume claims
result.volumeClaims.addAll( volumeClaims )
result.volumeClaims.addAll( other.volumeClaims )
// sec context
result.securityContext = other.securityContext ?: this.securityContext
// node selector
result.nodeSelector = other.nodeSelector ?: this.nodeSelector
// affinity
result.affinity = other.affinity ?: this.affinity
// pull policy
result.imagePullPolicy = other.imagePullPolicy ?: this.imagePullPolicy
// image secret
result.imagePullSecret = other.imagePullSecret ?: this.imagePullSecret
// labels
result.labels.putAll(labels)
result.labels.putAll(other.labels)
// annotations
result.annotations.putAll(annotations)
result.annotations.putAll(other.annotations)
// automount service account token
result.automountServiceAccountToken = other.automountServiceAccountToken & this.automountServiceAccountToken
// priority class name
result.priorityClassName = other.priorityClassName ?: this.priorityClassName
// tolerations
result.tolerations = other.tolerations ?: this.tolerations
// privileged execution
result.privileged = other.privileged!=null ? other.privileged : this.privileged
// scheduler name
result.schedulerName = other.schedulerName ?: this.schedulerName
// ttl seconds after finished (job)
result.ttlSecondsAfterFinished = other.ttlSecondsAfterFinished!=null ? other.ttlSecondsAfterFinished : this.ttlSecondsAfterFinished
// runtime class name
result.runtimeClassName = other.runtimeClassName ?: this.runtimeClassName
return result
}
}