2025-12-14 15:57:42 -03:00
|
|
|
# services/jenkins/helmrelease.yaml
|
|
|
|
|
apiVersion: helm.toolkit.fluxcd.io/v2
|
|
|
|
|
kind: HelmRelease
|
|
|
|
|
metadata:
|
|
|
|
|
name: jenkins
|
|
|
|
|
namespace: jenkins
|
|
|
|
|
spec:
|
|
|
|
|
interval: 30m
|
|
|
|
|
chart:
|
|
|
|
|
spec:
|
|
|
|
|
chart: jenkins
|
|
|
|
|
version: 5.8.114
|
|
|
|
|
sourceRef:
|
|
|
|
|
kind: HelmRepository
|
|
|
|
|
name: jenkins
|
|
|
|
|
namespace: flux-system
|
|
|
|
|
install:
|
2025-12-17 01:11:07 -03:00
|
|
|
timeout: 15m
|
2025-12-14 15:57:42 -03:00
|
|
|
remediation:
|
|
|
|
|
retries: 3
|
|
|
|
|
upgrade:
|
2025-12-17 01:11:07 -03:00
|
|
|
timeout: 15m
|
2025-12-14 15:57:42 -03:00
|
|
|
remediation:
|
|
|
|
|
retries: 3
|
|
|
|
|
remediateLastFailure: true
|
|
|
|
|
cleanupOnFail: true
|
2025-12-17 01:11:07 -03:00
|
|
|
rollback:
|
|
|
|
|
timeout: 15m
|
2025-12-14 15:57:42 -03:00
|
|
|
values:
|
|
|
|
|
controller:
|
|
|
|
|
jenkinsUrl: https://ci.bstein.dev
|
|
|
|
|
ingress:
|
|
|
|
|
enabled: true
|
|
|
|
|
hostName: ci.bstein.dev
|
|
|
|
|
ingressClassName: traefik
|
|
|
|
|
annotations:
|
|
|
|
|
cert-manager.io/cluster-issuer: letsencrypt
|
|
|
|
|
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
|
|
|
|
tls:
|
|
|
|
|
- secretName: jenkins-tls
|
|
|
|
|
hosts:
|
|
|
|
|
- ci.bstein.dev
|
2025-12-14 17:59:48 -03:00
|
|
|
installPlugins:
|
|
|
|
|
- kubernetes
|
|
|
|
|
- workflow-aggregator
|
|
|
|
|
- git
|
|
|
|
|
- configuration-as-code
|
|
|
|
|
- oic-auth
|
2025-12-16 20:21:33 -03:00
|
|
|
- job-dsl
|
2025-12-16 20:27:41 -03:00
|
|
|
- configuration-as-code-support
|
2025-12-14 15:57:42 -03:00
|
|
|
containerEnv:
|
|
|
|
|
- name: ENABLE_OIDC
|
2025-12-14 20:58:57 -03:00
|
|
|
value: "true"
|
2025-12-14 19:22:47 -03:00
|
|
|
- name: OIDC_ISSUER
|
|
|
|
|
value: "https://sso.bstein.dev/realms/atlas"
|
2025-12-14 15:57:42 -03:00
|
|
|
- name: OIDC_CLIENT_ID
|
|
|
|
|
valueFrom:
|
|
|
|
|
secretKeyRef:
|
|
|
|
|
name: jenkins-oidc
|
|
|
|
|
key: clientId
|
|
|
|
|
- name: OIDC_CLIENT_SECRET
|
|
|
|
|
valueFrom:
|
|
|
|
|
secretKeyRef:
|
|
|
|
|
name: jenkins-oidc
|
|
|
|
|
key: clientSecret
|
|
|
|
|
- name: OIDC_AUTH_URL
|
|
|
|
|
valueFrom:
|
|
|
|
|
secretKeyRef:
|
|
|
|
|
name: jenkins-oidc
|
|
|
|
|
key: authorizationUrl
|
|
|
|
|
- name: OIDC_TOKEN_URL
|
|
|
|
|
valueFrom:
|
|
|
|
|
secretKeyRef:
|
|
|
|
|
name: jenkins-oidc
|
|
|
|
|
key: tokenUrl
|
|
|
|
|
- name: OIDC_USERINFO_URL
|
|
|
|
|
valueFrom:
|
|
|
|
|
secretKeyRef:
|
|
|
|
|
name: jenkins-oidc
|
|
|
|
|
key: userInfoUrl
|
|
|
|
|
- name: OIDC_LOGOUT_URL
|
|
|
|
|
valueFrom:
|
|
|
|
|
secretKeyRef:
|
|
|
|
|
name: jenkins-oidc
|
|
|
|
|
key: logoutUrl
|
2025-12-17 01:47:33 -03:00
|
|
|
- name: GITEA_PAT_USERNAME
|
|
|
|
|
valueFrom:
|
|
|
|
|
secretKeyRef:
|
|
|
|
|
name: gitea-pat
|
|
|
|
|
key: username
|
|
|
|
|
- name: GITEA_PAT_TOKEN
|
|
|
|
|
valueFrom:
|
|
|
|
|
secretKeyRef:
|
|
|
|
|
name: gitea-pat
|
|
|
|
|
key: token
|
2025-12-17 00:37:37 -03:00
|
|
|
customInitContainers:
|
|
|
|
|
- name: clean-jcasc-stale
|
|
|
|
|
image: alpine:3.20
|
|
|
|
|
imagePullPolicy: IfNotPresent
|
|
|
|
|
command:
|
|
|
|
|
- sh
|
|
|
|
|
- -c
|
|
|
|
|
- |
|
|
|
|
|
set -euo pipefail
|
2025-12-17 02:23:54 -03:00
|
|
|
rm -f /var/jenkins_home/casc_configs/* || true
|
2025-12-17 00:37:37 -03:00
|
|
|
securityContext:
|
2025-12-17 01:11:07 -03:00
|
|
|
runAsNonRoot: true
|
2025-12-17 00:43:55 -03:00
|
|
|
runAsUser: 1000
|
|
|
|
|
runAsGroup: 1000
|
2025-12-17 00:37:37 -03:00
|
|
|
volumeMounts:
|
|
|
|
|
- name: jenkins-home
|
|
|
|
|
mountPath: /var/jenkins_home
|
2025-12-14 19:22:47 -03:00
|
|
|
initScripts:
|
|
|
|
|
oidc.groovy: |
|
2025-12-14 20:58:57 -03:00
|
|
|
import hudson.util.Secret
|
|
|
|
|
import jenkins.model.IdStrategy
|
2025-12-14 19:22:47 -03:00
|
|
|
import jenkins.model.Jenkins
|
|
|
|
|
import org.jenkinsci.plugins.oic.OicSecurityRealm
|
2025-12-14 20:58:57 -03:00
|
|
|
import org.jenkinsci.plugins.oic.OicServerWellKnownConfiguration
|
2025-12-16 20:33:03 -03:00
|
|
|
import hudson.security.FullControlOnceLoggedInAuthorizationStrategy
|
2025-12-14 19:22:47 -03:00
|
|
|
def env = System.getenv()
|
2025-12-14 20:58:57 -03:00
|
|
|
if (!(env['ENABLE_OIDC'] ?: 'false').toBoolean()) {
|
2025-12-14 19:22:47 -03:00
|
|
|
println("OIDC disabled (ENABLE_OIDC=false); keeping default security realm")
|
|
|
|
|
return
|
|
|
|
|
}
|
2025-12-14 20:58:57 -03:00
|
|
|
def required = ['OIDC_CLIENT_ID','OIDC_CLIENT_SECRET','OIDC_ISSUER']
|
2025-12-14 19:22:47 -03:00
|
|
|
if (!required.every { env[it] }) {
|
2025-12-17 01:11:07 -03:00
|
|
|
throw new IllegalStateException("OIDC enabled but missing vars: ${required.findAll { !env[it] }}")
|
2025-12-14 19:22:47 -03:00
|
|
|
}
|
|
|
|
|
try {
|
2025-12-14 20:58:57 -03:00
|
|
|
def wellKnown = "${env['OIDC_ISSUER']}/.well-known/openid-configuration"
|
|
|
|
|
def serverCfg = new OicServerWellKnownConfiguration(wellKnown)
|
|
|
|
|
serverCfg.setScopesOverride('openid profile email')
|
2025-12-14 19:22:47 -03:00
|
|
|
def realm = new OicSecurityRealm(
|
|
|
|
|
env['OIDC_CLIENT_ID'],
|
2025-12-14 20:58:57 -03:00
|
|
|
Secret.fromString(env['OIDC_CLIENT_SECRET']),
|
|
|
|
|
serverCfg,
|
|
|
|
|
false,
|
|
|
|
|
IdStrategy.CASE_INSENSITIVE,
|
|
|
|
|
IdStrategy.CASE_INSENSITIVE
|
2025-12-14 19:22:47 -03:00
|
|
|
)
|
2025-12-14 21:23:15 -03:00
|
|
|
realm.createProxyAwareResourceRetriver()
|
2025-12-14 20:58:57 -03:00
|
|
|
realm.setLogoutFromOpenidProvider(true)
|
|
|
|
|
realm.setPostLogoutRedirectUrl('https://ci.bstein.dev')
|
|
|
|
|
realm.setUserNameField('preferred_username')
|
|
|
|
|
realm.setFullNameFieldName('name')
|
|
|
|
|
realm.setEmailFieldName('email')
|
|
|
|
|
realm.setGroupsFieldName('groups')
|
|
|
|
|
realm.setRootURLFromRequest(true)
|
|
|
|
|
realm.setSendScopesInTokenRequest(true)
|
2025-12-14 19:22:47 -03:00
|
|
|
def j = Jenkins.get()
|
|
|
|
|
j.setSecurityRealm(realm)
|
2025-12-16 20:33:03 -03:00
|
|
|
def auth = new FullControlOnceLoggedInAuthorizationStrategy()
|
|
|
|
|
auth.setAllowAnonymousRead(false)
|
2025-12-16 20:16:18 -03:00
|
|
|
j.setAuthorizationStrategy(auth)
|
2025-12-14 19:22:47 -03:00
|
|
|
j.save()
|
2025-12-14 20:58:57 -03:00
|
|
|
println("Configured OIDC realm from init script (well-known)")
|
2025-12-14 19:22:47 -03:00
|
|
|
} catch (Exception e) {
|
|
|
|
|
println("Failed to configure OIDC realm: ${e}")
|
2025-12-17 01:11:07 -03:00
|
|
|
throw e
|
2025-12-14 19:22:47 -03:00
|
|
|
}
|
2025-12-16 19:26:46 -03:00
|
|
|
JCasC:
|
2025-12-17 02:23:54 -03:00
|
|
|
defaultConfig: false
|
2025-12-16 19:26:46 -03:00
|
|
|
configScripts:
|
2025-12-17 02:23:54 -03:00
|
|
|
base.yaml: |
|
|
|
|
|
jenkins:
|
|
|
|
|
disableRememberMe: false
|
|
|
|
|
mode: NORMAL
|
|
|
|
|
numExecutors: 0
|
|
|
|
|
labelString: ""
|
|
|
|
|
projectNamingStrategy: "standard"
|
|
|
|
|
markupFormatter:
|
|
|
|
|
plainText
|
|
|
|
|
clouds:
|
|
|
|
|
- kubernetes:
|
|
|
|
|
containerCapStr: "10"
|
|
|
|
|
defaultsProviderTemplate: ""
|
|
|
|
|
connectTimeout: "5"
|
|
|
|
|
readTimeout: "15"
|
|
|
|
|
jenkinsUrl: "http://jenkins.jenkins.svc.cluster.local:8080"
|
|
|
|
|
jenkinsTunnel: "jenkins-agent.jenkins.svc.cluster.local:50000"
|
|
|
|
|
skipTlsVerify: false
|
|
|
|
|
usageRestricted: false
|
|
|
|
|
maxRequestsPerHostStr: "32"
|
|
|
|
|
retentionTimeout: "5"
|
|
|
|
|
waitForPodSec: "600"
|
|
|
|
|
name: "kubernetes"
|
|
|
|
|
namespace: "jenkins"
|
|
|
|
|
restrictedPssSecurityContext: false
|
|
|
|
|
serverUrl: "https://kubernetes.default"
|
|
|
|
|
credentialsId: ""
|
|
|
|
|
podLabels:
|
|
|
|
|
- key: "jenkins/jenkins-jenkins-agent"
|
|
|
|
|
value: "true"
|
|
|
|
|
templates:
|
|
|
|
|
- name: "default"
|
|
|
|
|
namespace: "jenkins"
|
|
|
|
|
id: a23c9bbcd21e360a77d51b426f05bd7b8032d8fdedd6ffb97c436883ce6c5ffa
|
|
|
|
|
containers:
|
|
|
|
|
- name: "jnlp"
|
|
|
|
|
alwaysPullImage: false
|
|
|
|
|
args: "^${computer.jnlpmac} ^${computer.name}"
|
|
|
|
|
envVars:
|
|
|
|
|
- envVar:
|
|
|
|
|
key: "JENKINS_URL"
|
|
|
|
|
value: "http://jenkins.jenkins.svc.cluster.local:8080/"
|
|
|
|
|
image: "jenkins/inbound-agent:3355.v388858a_47b_33-3"
|
|
|
|
|
privileged: "false"
|
|
|
|
|
resourceLimitCpu: 512m
|
|
|
|
|
resourceLimitMemory: 512Mi
|
|
|
|
|
resourceRequestCpu: 512m
|
|
|
|
|
resourceRequestMemory: 512Mi
|
|
|
|
|
ttyEnabled: false
|
|
|
|
|
workingDir: /home/jenkins/agent
|
|
|
|
|
idleMinutes: 0
|
|
|
|
|
instanceCap: 2147483647
|
|
|
|
|
label: "jenkins-jenkins-agent "
|
|
|
|
|
nodeUsageMode: "NORMAL"
|
|
|
|
|
podRetention: Never
|
|
|
|
|
showRawYaml: true
|
|
|
|
|
serviceAccount: "default"
|
|
|
|
|
slaveConnectTimeoutStr: "100"
|
|
|
|
|
yamlMergeStrategy: override
|
|
|
|
|
inheritYamlMergeStrategy: false
|
|
|
|
|
slaveAgentPort: 50000
|
|
|
|
|
crumbIssuer:
|
|
|
|
|
standard:
|
|
|
|
|
excludeClientIPFromCrumb: true
|
|
|
|
|
security:
|
|
|
|
|
apiToken:
|
|
|
|
|
creationOfLegacyTokenEnabled: false
|
|
|
|
|
tokenGenerationOnCreationEnabled: false
|
|
|
|
|
usageStatisticsEnabled: true
|
|
|
|
|
unclassified:
|
2025-12-16 19:26:46 -03:00
|
|
|
creds.yaml: |
|
|
|
|
|
credentials:
|
|
|
|
|
system:
|
|
|
|
|
domainCredentials:
|
|
|
|
|
- credentials:
|
|
|
|
|
- usernamePassword:
|
|
|
|
|
scope: GLOBAL
|
|
|
|
|
id: gitea-pat
|
2025-12-17 01:47:33 -03:00
|
|
|
username: "${GITEA_PAT_USERNAME}"
|
|
|
|
|
password: "${GITEA_PAT_TOKEN}"
|
|
|
|
|
description: "Gitea PAT for pipelines"
|
2025-12-16 19:26:46 -03:00
|
|
|
jobs.yaml: |
|
|
|
|
|
jobs:
|
|
|
|
|
- script: |
|
|
|
|
|
pipelineJob('harbor-arm-build') {
|
2025-12-17 01:58:10 -03:00
|
|
|
triggers {
|
|
|
|
|
scm('H/5 * * * *')
|
|
|
|
|
}
|
2025-12-16 19:26:46 -03:00
|
|
|
definition {
|
|
|
|
|
cpsScm {
|
|
|
|
|
scm {
|
|
|
|
|
git {
|
|
|
|
|
remote {
|
|
|
|
|
url('https://scm.bstein.dev/bstein/harbor-arm-build.git')
|
|
|
|
|
credentials('gitea-pat')
|
|
|
|
|
}
|
|
|
|
|
branches('*/master')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-12-14 15:57:42 -03:00
|
|
|
persistence:
|
|
|
|
|
enabled: true
|
|
|
|
|
storageClass: astreae
|
|
|
|
|
size: 50Gi
|
|
|
|
|
serviceAccount:
|
|
|
|
|
create: true
|