k8s-produ-lib.groovy 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /**
  2. * Harbor image promote + optional ACK deploy (loaded from Jenkinsfile, not a job entry).
  3. */
  4. def resolveTargetTag(def script, String targetTagParam) {
  5. def t = (targetTagParam ?: '').trim()
  6. return t ?: "produ-${script.env.BUILD_NUMBER}"
  7. }
  8. def requireSourceTag(def script, String sourceTag) {
  9. def srcTag = (sourceTag ?: '').trim()
  10. if (!srcTag) {
  11. script.error('SOURCE_TAG is required (e.g. uat-latest or uat-build-42). Check Harbor for an existing tag.')
  12. }
  13. return srcTag
  14. }
  15. def promoteHarborImages(def script, List services, Map cfg) {
  16. def regHost = cfg.harborRegistry.trim()
  17. def proj = cfg.harborProject.trim()
  18. def srcTag = requireSourceTag(script, cfg.sourceTag)
  19. def tgtTag = cfg.targetTag
  20. def dryRun = cfg.dryRun == true
  21. services.each { s ->
  22. def src = "${regHost}/${proj}/${s.prodDir}:${srcTag}"
  23. def tgt = "${regHost}/${proj}/${s.prodDir}:${tgtTag}"
  24. echo ">>> promote ${s.prodDir}: ${src} -> ${tgt}"
  25. if (dryRun) {
  26. return
  27. }
  28. }
  29. if (dryRun) {
  30. return
  31. }
  32. script.withCredentials([script.usernamePassword(
  33. credentialsId: cfg.harborCredentialsId,
  34. usernameVariable: 'HARBOR_USER',
  35. passwordVariable: 'HARBOR_PASS',
  36. )]) {
  37. script.sh """
  38. set -e
  39. echo "\${HARBOR_PASS}" | docker login ${regHost} -u "\${HARBOR_USER}" --password-stdin
  40. """
  41. services.each { s ->
  42. def src = "${regHost}/${proj}/${s.prodDir}:${srcTag}"
  43. def tgt = "${regHost}/${proj}/${s.prodDir}:${tgtTag}"
  44. script.sh """
  45. set -e
  46. docker pull ${src}
  47. docker tag ${src} ${tgt}
  48. docker push ${tgt}
  49. """
  50. }
  51. }
  52. }
  53. def deployToAck(def script, Map cfg) {
  54. def ns = cfg.k8sNamespace
  55. def imageRef = cfg.imageRef
  56. def strategy = cfg.deployStrategy
  57. def targetDeploy = strategy == 'canary' ? cfg.deploymentCanary : cfg.deploymentStable
  58. def canaryWeight = cfg.canaryWeight
  59. def ingressCanary = cfg.ingressCanary
  60. def kubeCreds = cfg.kubeCredentialsId
  61. script.withCredentials([script.file(credentialsId: kubeCreds, variable: 'KUBECONFIG')]) {
  62. script.sh """
  63. set -e
  64. kubectl config current-context
  65. kubectl -n ${ns} set image deployment/${targetDeploy} app=${imageRef} --record
  66. kubectl -n ${ns} rollout status deployment/${targetDeploy} --timeout=300s
  67. """
  68. if (strategy == 'canary') {
  69. script.sh """
  70. set -e
  71. kubectl -n ${ns} annotate ingress ${ingressCanary} \\
  72. nginx.ingress.kubernetes.io/canary=true \\
  73. nginx.ingress.kubernetes.io/canary-weight=${canaryWeight} \\
  74. --overwrite
  75. """
  76. }
  77. }
  78. }
  79. /** Single-service promote + ACK. Use script.params / script.env (do not pass params/env as args: CPS breaks method dispatch). */
  80. def promoteOneServiceToAck(def script, Map svc) {
  81. def regHost = script.params.HARBOR_REGISTRY.trim()
  82. def proj = script.params.HARBOR_PROJECT.trim()
  83. def srcTag = requireSourceTag(script, script.params.SOURCE_TAG)
  84. def tgtTag = resolveTargetTag(script, script.params.TARGET_TAG)
  85. def dryRun = script.params.DRY_RUN == true
  86. def strategy = script.params.DEPLOY_STRATEGY ?: 'rolling'
  87. script.env.TARGET_TAG_RESOLVED = tgtTag
  88. script.env.IMAGE_REF = "${regHost}/${proj}/${svc.prodDir}:${tgtTag}"
  89. promoteHarborImages(script, [svc], [
  90. harborRegistry: regHost,
  91. harborProject: proj,
  92. sourceTag: srcTag,
  93. targetTag: tgtTag,
  94. harborCredentialsId: script.env.HARBOR_CREDENTIALS,
  95. dryRun: dryRun,
  96. ])
  97. if (dryRun || strategy == 'skip') {
  98. return
  99. }
  100. deployToAck(script, [
  101. k8sNamespace: script.params.K8S_NAMESPACE,
  102. imageRef: script.env.IMAGE_REF,
  103. deployStrategy: strategy == 'canary' ? 'canary' : 'rolling',
  104. deploymentStable: svc.deployName,
  105. deploymentCanary: "${svc.deployName}-canary",
  106. ingressCanary: "${svc.deployName}-canary",
  107. canaryWeight: (script.params.CANARY_WEIGHT ?: '10').trim(),
  108. kubeCredentialsId: script.env.KUBECONFIG_CREDENTIALS,
  109. ])
  110. }
  111. return this