woodpecker-helm3/internal/helm/plan.go

143 lines
3.1 KiB
Go

package helm
import (
"errors"
"fmt"
"github.com/pelotech/drone-helm3/internal/env"
"github.com/pelotech/drone-helm3/internal/run"
"os"
)
const (
kubeConfigTemplate = "/root/.kube/config.tpl"
kubeConfigFile = "/root/.kube/config"
)
// A Step is one step in the plan.
type Step interface {
Prepare() error
Execute() error
}
// A Plan is a series of steps to perform.
type Plan struct {
steps []Step
cfg env.Config
}
// NewPlan makes a plan for running a helm operation.
func NewPlan(cfg env.Config) (*Plan, error) {
p := Plan{
cfg: cfg,
}
if cfg.UpdateDependencies && cfg.DependenciesAction != "" {
return nil, errors.New("update_dependencies is deprecated and cannot be provided together with dependencies_action")
}
p.steps = (*determineSteps(cfg))(cfg)
for i, step := range p.steps {
if cfg.Debug {
fmt.Fprintf(os.Stderr, "calling %T.Prepare (step %d)\n", step, i)
}
if err := step.Prepare(); err != nil {
err = fmt.Errorf("while preparing %T step: %w", step, err)
return nil, err
}
}
return &p, nil
}
// determineSteps is primarily for the tests' convenience: it allows testing the "which stuff should
// we do" logic without building a config that meets all the steps' requirements.
func determineSteps(cfg env.Config) *func(env.Config) []Step {
switch cfg.Command {
case "upgrade":
return &upgrade
case "uninstall", "delete":
return &uninstall
case "lint":
return &lint
case "help":
return &help
default:
switch cfg.DroneEvent {
case "push", "tag", "deployment", "pull_request", "promote", "rollback":
return &upgrade
case "delete":
return &uninstall
default:
return &help
}
}
}
// Execute runs each step in the plan, aborting and reporting on error
func (p *Plan) Execute() error {
for i, step := range p.steps {
if p.cfg.Debug {
fmt.Fprintf(p.cfg.Stderr, "calling %T.Execute (step %d)\n", step, i)
}
if err := step.Execute(); err != nil {
return fmt.Errorf("while executing %T step: %w", step, err)
}
}
return nil
}
var upgrade = func(cfg env.Config) []Step {
var steps []Step
if !cfg.SkipKubeconfig {
steps = append(steps, run.NewInitKube(cfg, kubeConfigTemplate, kubeConfigFile))
}
for _, repo := range cfg.AddRepos {
steps = append(steps, run.NewAddRepo(cfg, repo))
}
if cfg.DependenciesAction != "" {
steps = append(steps, run.NewDepAction(cfg))
}
if cfg.UpdateDependencies {
steps = append(steps, run.NewDepUpdate(cfg))
}
steps = append(steps, run.NewUpgrade(cfg))
return steps
}
var uninstall = func(cfg env.Config) []Step {
var steps []Step
if !cfg.SkipKubeconfig {
steps = append(steps, run.NewInitKube(cfg, kubeConfigTemplate, kubeConfigFile))
}
if cfg.UpdateDependencies {
steps = append(steps, run.NewDepUpdate(cfg))
}
steps = append(steps, run.NewUninstall(cfg))
return steps
}
var lint = func(cfg env.Config) []Step {
var steps []Step
for _, repo := range cfg.AddRepos {
steps = append(steps, run.NewAddRepo(cfg, repo))
}
if cfg.UpdateDependencies {
steps = append(steps, run.NewDepUpdate(cfg))
}
steps = append(steps, run.NewLint(cfg))
return steps
}
var help = func(cfg env.Config) []Step {
return []Step{run.NewHelp(cfg)}
}