// 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 = [ [ false, 'plecianki.pl'], [ false, 'kopama.com.pl', 'www'], [ false, 'bodypainter.eu', "www", "mail", "stat"], [ false, 'themself.eu', "www", "mail", "stat", "massage", "driving", "kopama" ], [ false, "artiks.tk", "www", "mail", "api", "angular", "bodypainter", "themself","arti24"], [ false, "arti24.eu", "www", "api", "angular", "ai", "job-finder", "zaklik"] ] def createCert(domains) { echo "Server ENV = ${SERVER_ENV}" echo "Certbot image = ${CERTBOT_IMAGE}" def toCreateDomains = [] for (domain in domains) { def force = domain[0] def name = domain[1] def fileName = "${baseCertPath}/${name}/cert.pem" def currentDomains = [] def daysLeft = null // Get existing certificate data if exists if (fileExists(fileName)) { def certInfo = sh( script: "openssl x509 -in ${fileName} -text -noout | grep -o 'DNS:[^,]*' | sed 's/DNS://g'", returnStdout: true ).trim() if (certInfo) { currentDomains = certInfo.split('\n').collect { it.trim() } } // Calculate days until expiration def expiryUnix = sh( script: "openssl x509 -enddate -noout -in ${fileName} | cut -d= -f2 | xargs -I{} date -d {} +%s", returnStdout: true ).trim() if (expiryUnix.isNumber()) { def nowUnix = sh(script: "date +%s", returnStdout: true).trim().toLong() daysLeft = (expiryUnix.toLong() - nowUnix) / (60 * 60 * 24) } } // Build expected domains list def expectedDomains = [name] + domain[2..-1].collect { "${it}.${name}" } // Check if certificate needs renewal 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 domains: ${expectedDomains - currentDomains}, expires in: ${daysLeft ?: 'unknown'} days)" toCreateDomains.add(domain) } else { echo "Certificate for '${name}' is OK (expires in ${daysLeft} days)" } } echo "Certificates to create/renew: ${toCreateDomains.collect { it[1] }}" if (toCreateDomains.isEmpty()) { echo "All certificates are up to date. Nothing to create/renew." return } dir(workDir) { for (domain in toCreateDomains) { def name = domain[1] def subDomains = domain[2..-1].collect { "-d ${it}.${name}" }.join(' ') sh """ ${letsEncryptCommand} run --rm certbot certonly \ --webroot -w /var/www/certbot \ --cert-name='${name}' \ --non-interactive --agree-tos \ --preferred-challenges http \ --email ${email} \ -d ${name} ${subDomains} """ } } } pipeline { agent any stages { stage('Make https cert for my domains') { steps { script { createCert(domainsToCert) } } } } }