Merge pull request #86 from obukhov/add-dependecies-action
Add dependecies action
This commit is contained in:
commit
d7a9eccb13
BIN
build/drone-helm
Executable file
BIN
build/drone-helm
Executable file
Binary file not shown.
|
@ -37,6 +37,7 @@ Installations are triggered when the `mode` setting is "upgrade." They can also
|
|||
| kube_certificate | string | | kubernetes_certificate | Base64 encoded TLS certificate used by the Kubernetes cluster's certificate authority. |
|
||||
| chart_version | string | | | Specific chart version to install. |
|
||||
| dry_run | boolean | | | Pass `--dry-run` to `helm upgrade`. |
|
||||
| dependencies_action | string | | | Calls `helm dependency build` OR `helm dependency update` before running the main command. Possible values: `build`, `update`. |
|
||||
| wait_for_upgrade | boolean | | wait | Wait until kubernetes resources are in a ready state before marking the installation successful. |
|
||||
| timeout | duration | | | Timeout for any *individual* Kubernetes operation. The installation's full runtime may exceed this duration. |
|
||||
| force_upgrade | boolean | | force | Pass `--force` to `helm upgrade`. |
|
||||
|
|
3
internal/env/config.go
vendored
3
internal/env/config.go
vendored
|
@ -23,7 +23,8 @@ type Config struct {
|
|||
// Configuration for drone-helm itself
|
||||
Command string `envconfig:"mode"` // Helm command to run
|
||||
DroneEvent string `envconfig:"drone_build_event"` // Drone event that invoked this plugin.
|
||||
UpdateDependencies bool `split_words:"true"` // Call `helm dependency update` before the main command
|
||||
UpdateDependencies bool `split_words:"true"` // [Deprecated] Call `helm dependency update` before the main command (deprecated, use dependencies_action: update instead)
|
||||
DependenciesAction string `split_words:"true"` // Call `helm dependency build` or `helm dependency update` before the main command
|
||||
AddRepos []string `split_words:"true"` // Call `helm repo add` before the main command
|
||||
RepoCertificate string `envconfig:"repo_certificate"` // The Helm chart repository's self-signed certificate (must be base64-encoded)
|
||||
RepoCACertificate string `envconfig:"repo_ca_certificate"` // The Helm chart repository CA's self-signed certificate (must be base64-encoded)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package helm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/pelotech/drone-helm3/internal/env"
|
||||
"github.com/pelotech/drone-helm3/internal/run"
|
||||
|
@ -30,6 +31,10 @@ func NewPlan(cfg env.Config) (*Plan, error) {
|
|||
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 {
|
||||
|
@ -91,9 +96,15 @@ var upgrade = func(cfg env.Config) []Step {
|
|||
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
|
||||
|
|
59
internal/run/depaction.go
Normal file
59
internal/run/depaction.go
Normal file
|
@ -0,0 +1,59 @@
|
|||
package run
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/pelotech/drone-helm3/internal/env"
|
||||
)
|
||||
|
||||
const (
|
||||
actionBuild = "build"
|
||||
actionUpdate = "update"
|
||||
)
|
||||
|
||||
// DepAction is an execution step that calls `helm dependency update` or `helm dependency build` when executed.
|
||||
type DepAction struct {
|
||||
*config
|
||||
chart string
|
||||
cmd cmd
|
||||
action string
|
||||
}
|
||||
|
||||
// NewDepAction creates a DepAction using fields from the given Config. No validation is performed at this time.
|
||||
func NewDepAction(cfg env.Config) *DepAction {
|
||||
return &DepAction{
|
||||
config: newConfig(cfg),
|
||||
chart: cfg.Chart,
|
||||
action: cfg.DependenciesAction,
|
||||
}
|
||||
}
|
||||
|
||||
// Execute executes the `helm upgrade` command.
|
||||
func (d *DepAction) Execute() error {
|
||||
return d.cmd.Run()
|
||||
}
|
||||
|
||||
// Prepare gets the DepAction ready to execute.
|
||||
func (d *DepAction) Prepare() error {
|
||||
if d.chart == "" {
|
||||
return fmt.Errorf("chart is required")
|
||||
}
|
||||
|
||||
args := d.globalFlags()
|
||||
|
||||
if d.action != actionBuild && d.action != actionUpdate {
|
||||
return errors.New("unknown dependency_action: " + d.action)
|
||||
}
|
||||
|
||||
args = append(args, "dependency", d.action, d.chart)
|
||||
|
||||
d.cmd = command(helmBin, args...)
|
||||
d.cmd.Stdout(d.stdout)
|
||||
d.cmd.Stderr(d.stderr)
|
||||
|
||||
if d.debug {
|
||||
fmt.Fprintf(d.stderr, "Generated command: '%s'\n", d.cmd.String())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
131
internal/run/depaction_test.go
Normal file
131
internal/run/depaction_test.go
Normal file
|
@ -0,0 +1,131 @@
|
|||
package run
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/pelotech/drone-helm3/internal/env"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type DepActionTestSuite struct {
|
||||
suite.Suite
|
||||
ctrl *gomock.Controller
|
||||
mockCmd *Mockcmd
|
||||
originalCommand func(string, ...string) cmd
|
||||
}
|
||||
|
||||
func (suite *DepActionTestSuite) BeforeTest(_, _ string) {
|
||||
suite.ctrl = gomock.NewController(suite.T())
|
||||
suite.mockCmd = NewMockcmd(suite.ctrl)
|
||||
|
||||
suite.originalCommand = command
|
||||
command = func(path string, args ...string) cmd { return suite.mockCmd }
|
||||
}
|
||||
|
||||
func (suite *DepActionTestSuite) AfterTest(_, _ string) {
|
||||
command = suite.originalCommand
|
||||
}
|
||||
|
||||
func TestDepActionTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(DepActionTestSuite))
|
||||
}
|
||||
|
||||
func (suite *DepActionTestSuite) TestNewDepAction() {
|
||||
cfg := env.Config{
|
||||
Chart: "scatterplot",
|
||||
}
|
||||
d := NewDepAction(cfg)
|
||||
suite.Equal("scatterplot", d.chart)
|
||||
}
|
||||
|
||||
func (suite *DepActionTestSuite) TestPrepareAndExecuteBuild() {
|
||||
defer suite.ctrl.Finish()
|
||||
|
||||
stdout := strings.Builder{}
|
||||
stderr := strings.Builder{}
|
||||
cfg := env.Config{
|
||||
Chart: "your_top_songs_2019",
|
||||
Stdout: &stdout,
|
||||
Stderr: &stderr,
|
||||
DependenciesAction: "build",
|
||||
}
|
||||
|
||||
command = func(path string, args ...string) cmd {
|
||||
suite.Equal(helmBin, path)
|
||||
suite.Equal([]string{"dependency", "build", "your_top_songs_2019"}, args)
|
||||
|
||||
return suite.mockCmd
|
||||
}
|
||||
suite.mockCmd.EXPECT().
|
||||
Stdout(&stdout)
|
||||
suite.mockCmd.EXPECT().
|
||||
Stderr(&stderr)
|
||||
suite.mockCmd.EXPECT().
|
||||
Run().
|
||||
Times(1)
|
||||
|
||||
d := NewDepAction(cfg)
|
||||
|
||||
suite.Require().NoError(d.Prepare())
|
||||
suite.NoError(d.Execute())
|
||||
}
|
||||
|
||||
func (suite *DepActionTestSuite) TestPrepareAndExecuteUpdate() {
|
||||
defer suite.ctrl.Finish()
|
||||
|
||||
stdout := strings.Builder{}
|
||||
stderr := strings.Builder{}
|
||||
cfg := env.Config{
|
||||
Chart: "your_top_songs_2019",
|
||||
Stdout: &stdout,
|
||||
Stderr: &stderr,
|
||||
DependenciesAction: "update",
|
||||
}
|
||||
|
||||
command = func(path string, args ...string) cmd {
|
||||
suite.Equal(helmBin, path)
|
||||
suite.Equal([]string{"dependency", "update", "your_top_songs_2019"}, args)
|
||||
|
||||
return suite.mockCmd
|
||||
}
|
||||
suite.mockCmd.EXPECT().
|
||||
Stdout(&stdout)
|
||||
suite.mockCmd.EXPECT().
|
||||
Stderr(&stderr)
|
||||
suite.mockCmd.EXPECT().
|
||||
Run().
|
||||
Times(1)
|
||||
|
||||
d := NewDepAction(cfg)
|
||||
|
||||
suite.Require().NoError(d.Prepare())
|
||||
suite.NoError(d.Execute())
|
||||
}
|
||||
|
||||
func (suite *DepActionTestSuite) TestPrepareAndExecuteUnknown() {
|
||||
defer suite.ctrl.Finish()
|
||||
|
||||
stdout := strings.Builder{}
|
||||
stderr := strings.Builder{}
|
||||
cfg := env.Config{
|
||||
Chart: "your_top_songs_2019",
|
||||
Stdout: &stdout,
|
||||
Stderr: &stderr,
|
||||
DependenciesAction: "downgrade",
|
||||
}
|
||||
|
||||
d := NewDepAction(cfg)
|
||||
suite.Require().Equal(errors.New("unknown dependency_action: downgrade"), d.Prepare())
|
||||
}
|
||||
|
||||
func (suite *DepActionTestSuite) TestPrepareChartRequired() {
|
||||
d := NewDepAction(env.Config{})
|
||||
|
||||
suite.mockCmd.EXPECT().Stdout(gomock.Any()).AnyTimes()
|
||||
suite.mockCmd.EXPECT().Stderr(gomock.Any()).AnyTimes()
|
||||
|
||||
err := d.Prepare()
|
||||
suite.EqualError(err, "chart is required")
|
||||
}
|
Loading…
Reference in a new issue