k8s-produ-lib.groovy 4.3 KB

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