vendredi 22 septembre 2023

Is there a design pattern I can use to implement this Jenkins pipeline code?

I want to write Jenkins pipeline code (Groovy) to deploy Docker containers in ECS. Say I capture this behavior in the following classes, with each concrete class representing a Docker container to be deployed to ECS. Depending on the container, I need to run certain tasks (or none at all) before deploying to ECS, then common tasks to actually deploy to ECS, then certain tasks post deployment to ECS. All files are in the com.somepath class path.

package com.somepath
abstract class EcsService {
  runPreDeployTasks() {throw new Exception("Implement in sub-class.")}
  runDeployTasks() { println "Do something common to all sub-classes" }
  runPostDeployTasks() {throw new Exception("Implement in sub-class.")}
}

package com.somepath
class AdminService extends EcsService {
  AdminService() {}
  def runPreDeployTasks() {
    println "runPreDeployTasks: ${this.getClass().getSimpleName()}"
  }
  def runPostDeployTasks() {
    println "runPostDeployTasks: ${this.getClass().getSimpleName()}"
  }
}

package com.somepath
class ProcService extends EcsService {
  ProcService() {}
  def runPreDeployTasks(final boolean singleSvc=false) {
    println "runPreDeployTasks: ${this.getClass().getSimpleName()}"
  }
  def runPostDeployTasks(final boolean singleSvc=false) {
    println "runDeployTasks: ${this.getClass().getSimpleName()}"
  }
}

Then this is the API to Jenkins

package com.somepath
import com.somepath.EcsService
import com.somepath.AdminService
import com.somepath.ProcService

class Deployer {
  Deployer() {}

  def deployServices() {
    def obj = new AdminService()
    svcList.add(obj)
    obj = new ProcService()
    svcList.add(obj)

    svcList.each { svc ->
      svc.runPreDeployTasks()
      svc.runDeployTasks()
      svc.runPostDeployTasks()
    }
  }

  List<EcsService> svcList = []
}

Then the Jenkins pipeline

@Library('share-lib') _
import com.somepath.Deployer

node("node1") {
  def obj = new Deployer()
  obj.deployServices()
}

Is there a better way to do this using a classic design pattern? Thanks.

Aucun commentaire:

Enregistrer un commentaire