a21848484b
This fixes the run package's leaky abstraction; other packages no longer need to know or care that run.Config even exists. Note that since the various Steps now depend on having a non-nil pointer to a run.Config, it's unsafe (or at least risky) to initialize them directly. They should be created with their NewSTEPNAME functions. All their fields are now private, to reflect this.
128 lines
2.8 KiB
Go
128 lines
2.8 KiB
Go
package helm
|
|
|
|
import (
|
|
"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,
|
|
}
|
|
|
|
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
|
|
steps = append(steps, run.NewInitKube(cfg, kubeConfigTemplate, kubeConfigFile))
|
|
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.NewUpgrade(cfg))
|
|
|
|
return steps
|
|
}
|
|
|
|
var uninstall = func(cfg env.Config) []Step {
|
|
var steps []Step
|
|
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)}
|
|
}
|