From 969a19f584ad79c4a728a1a8c0a66b3e4927db6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Artur=20Ku=C5=9B?= Date: Thu, 19 Feb 2026 18:13:40 +0100 Subject: [PATCH] changing certificate renewal --- .../lets-encrypt-create-cert.jenkinsfile | 73 ++++++++++--------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/deploy-this/lets-encrypt/lets-encrypt-create-cert.jenkinsfile b/deploy-this/lets-encrypt/lets-encrypt-create-cert.jenkinsfile index 99b922d..7733418 100755 --- a/deploy-this/lets-encrypt/lets-encrypt-create-cert.jenkinsfile +++ b/deploy-this/lets-encrypt/lets-encrypt-create-cert.jenkinsfile @@ -1,24 +1,18 @@ -// Define common paths and variables -def baseCertPath = '/_docker_data_/letsencrypt/live' -def letsEncryptCommand = "docker compose --file lets-encrypt.yml --env-file lets.env" -def email = env.LETSENCRYPT_EMAIL ?: 'kusartur@gmail.com' -def workDir = "/_sd_/_programs_/proxy-nginx/deploy-this/lets-encrypt" - -def domainsToCert = [ +def domainsToCert = [ [ false, 'plecianki.pl'], [ false, 'kopama.com.pl'], [ false, 'kopana.com.pl'], - [ false, 'bodypainter.eu'], + [ false, 'bodypainter.eu'], [ false, 'themself.eu', "massage" ], [ false, "artiks.tk" ], [ false, "arti24.eu", "api", "angular", "plecianki", "git" ], [ false, "katb.pl"], [ false, "kursy.kopama.pl"], [ false, "statistics.kopama.pl"] - ] def createCert(domains) { + def baseCertPath = env.CERTS_PATH ?: '/_docker_data_/letsencrypt/live' def workDir = env.WORK_DIR ?: "/_sd_/_programs_/proxy-nginx/deploy-this/lets-encrypt" def letsEncryptCommand = "docker compose --file lets-encrypt.yml --env-file lets.env" @@ -27,6 +21,7 @@ def createCert(domains) { def toCreateDomains = [] for (domain in domains) { + def force = domain[0] def name = domain[1] def fileName = "${baseCertPath}/${name}/cert.pem" @@ -35,52 +30,61 @@ def createCert(domains) { def daysLeft = null if (fileExists(fileName)) { + + // ✅ poprawne pobieranie SAN def certInfo = sh( script: """ - openssl x509 -in ${fileName} -text -noout \ - | grep 'DNS:' \ - | sed 's/.*DNS://;s/, /\\n/g' + openssl x509 -in ${fileName} -noout -ext subjectAltName \ + | sed -n 's/ *DNS://gp' \ + | tr ',' '\\n' \ + | sed 's/^ *//' """, returnStdout: true ).trim() if (certInfo) { - currentDomains = certInfo.split('\n').collect { it.trim() } + currentDomains = certInfo.split('\\n').collect { it.trim() } } - def expiryUnix = sh( - script: "openssl x509 -enddate -noout -in ${fileName} | cut -d= -f2 | xargs -I{} date -d {} +%s", - returnStdout: true - ).trim() + // ✅ poprawne liczenie dni + try { + def expiryUnix = sh( + script: "date -d \"\$(openssl x509 -enddate -noout -in ${fileName} | cut -d= -f2)\" +%s", + returnStdout: true + ).trim().toLong() - if (expiryUnix?.isLong()) { def nowUnix = sh(script: "date +%s", returnStdout: true).trim().toLong() - daysLeft = (expiryUnix.toLong() - nowUnix) / (60 * 60 * 24) + daysLeft = (expiryUnix - nowUnix) / (60 * 60 * 24) + + } catch (e) { + echo "Cannot parse expiry for ${name}" } } def subList = (domain.size() > 2) ? domain[2..-1] : [] def expectedDomains = [name] + subList.collect { "${it}.${name}" } - def needsRenewal = force || - !fileExists(fileName) || - currentDomains.size() != expectedDomains.size() || - !currentDomains.containsAll(expectedDomains) || - (daysLeft != null && daysLeft < 30) + def needsRenewal = + force || + !fileExists(fileName) || + currentDomains.size() != expectedDomains.size() || + !currentDomains.containsAll(expectedDomains) || + (daysLeft != null && daysLeft < 30) if (needsRenewal) { - echo "Certificate for '${name}' needs renewal (force: ${force}, missing: ${expectedDomains - currentDomains}, expires in: ${daysLeft ?: 'unknown'} days)" + echo "Renewing '${name}' (force=${force}, expires in=${daysLeft ?: 'unknown'} days)" toCreateDomains.add(domain) } else { - echo "Certificate for '${name}' is OK (expires in ${daysLeft} days)" + echo "Certificate for '${name}' OK (expires in ${daysLeft} days)" } } - echo "Certificates to create/renew: ${toCreateDomains.collect { it[1] }}" - if (!toCreateDomains.isEmpty()) { + dir(workDir) { + for (domain in toCreateDomains) { + def name = domain[1] def subList = (domain.size() > 2) ? domain[2..-1] : [] def subDomains = subList.collect { "-d ${it}.${name}" }.join(' ') @@ -88,29 +92,30 @@ def createCert(domains) { def cmd = """ ${letsEncryptCommand} run --rm certbot certonly \ --webroot -w /var/www/certbot \ - --cert-name='${name}' \ + --cert-name ${name} \ --non-interactive --agree-tos \ --preferred-challenges http \ - --expand \ --email ${email} \ + --force-renewal \ -d ${name} ${subDomains} """.stripIndent() + sh(cmd) } } + } else { - echo "All certificates are up to date. Nothing to create/renew." + echo "All certificates are up to date." } } - pipeline { - agent any + agent any stages { stage('Make https cert for my domains') { steps { script { - createCert(domainsToCert) + createCert(domainsToCert) } } }