232bb5eb96
These comments were a reasonable attempt at ensuring the documentation matched reality, but the checkbox in the pull request template is much more likely to produce results.
150 lines
3.1 KiB
Go
150 lines
3.1 KiB
Go
package helm
|
|
|
|
import (
|
|
"fmt"
|
|
"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(run.Config) error
|
|
Execute(run.Config) error
|
|
}
|
|
|
|
// A Plan is a series of steps to perform.
|
|
type Plan struct {
|
|
steps []Step
|
|
cfg Config
|
|
runCfg run.Config
|
|
}
|
|
|
|
// NewPlan makes a plan for running a helm operation.
|
|
func NewPlan(cfg Config) (*Plan, error) {
|
|
p := Plan{
|
|
cfg: cfg,
|
|
runCfg: run.Config{
|
|
Debug: cfg.Debug,
|
|
Values: cfg.Values,
|
|
StringValues: cfg.StringValues,
|
|
ValuesFiles: cfg.ValuesFiles,
|
|
Namespace: cfg.Namespace,
|
|
Stdout: cfg.Stdout,
|
|
Stderr: cfg.Stderr,
|
|
},
|
|
}
|
|
|
|
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(p.runCfg); 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 Config) *func(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:
|
|
panic("not implemented")
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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(p.runCfg); err != nil {
|
|
return fmt.Errorf("while executing %T step: %w", step, err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
var upgrade = func(cfg Config) []Step {
|
|
steps := initKube(cfg)
|
|
|
|
steps = append(steps, &run.Upgrade{
|
|
Chart: cfg.Chart,
|
|
Release: cfg.Release,
|
|
ChartVersion: cfg.ChartVersion,
|
|
DryRun: cfg.DryRun,
|
|
Wait: cfg.Wait,
|
|
ReuseValues: cfg.ReuseValues,
|
|
Timeout: cfg.Timeout,
|
|
Force: cfg.Force,
|
|
})
|
|
|
|
return steps
|
|
}
|
|
|
|
var uninstall = func(cfg Config) []Step {
|
|
steps := initKube(cfg)
|
|
steps = append(steps, &run.Uninstall{
|
|
Release: cfg.Release,
|
|
DryRun: cfg.DryRun,
|
|
})
|
|
|
|
return steps
|
|
}
|
|
|
|
var lint = func(cfg Config) []Step {
|
|
lint := &run.Lint{
|
|
Chart: cfg.Chart,
|
|
}
|
|
|
|
return []Step{lint}
|
|
}
|
|
|
|
var help = func(cfg Config) []Step {
|
|
help := &run.Help{}
|
|
return []Step{help}
|
|
}
|
|
|
|
func initKube(cfg Config) []Step {
|
|
return []Step{
|
|
&run.InitKube{
|
|
SkipTLSVerify: cfg.SkipTLSVerify,
|
|
Certificate: cfg.Certificate,
|
|
APIServer: cfg.APIServer,
|
|
ServiceAccount: cfg.ServiceAccount,
|
|
Token: cfg.KubeToken,
|
|
TemplateFile: kubeConfigTemplate,
|
|
ConfigFile: kubeConfigFile,
|
|
},
|
|
}
|
|
}
|