Skip to content

Commit

Permalink
Upgrade command (#659)
Browse files Browse the repository at this point in the history
* PoC of upgrade command

* Format

* Fix

* Fix formatting

* Fixed

* Add tests for kudo client

* Format

* Upgrade unit tests

* Formatting

* Missing file

* Review feedback

* Parameters merge patch in progress

* Params

* Formats

* Missing file

* PR comments
  • Loading branch information
alenkacz authored and kudo-ci committed Jul 31, 2019
1 parent 182c83d commit 5e2dfd0
Show file tree
Hide file tree
Showing 12 changed files with 609 additions and 83 deletions.
2 changes: 1 addition & 1 deletion config/samples/first-operator/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ spec:
selector:
matchLabels:
app: nginx
replicas: {{ .Params.Replicas }} # tells deployment to run 2 pods matching the template
replicas: {{ .Params.replicas }} # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ require (
github.com/pborman/uuid v0.0.0-20180906182336-adf5a7427709 // indirect
github.com/pkg/errors v0.8.1
github.com/pmezard/go-difflib v1.0.0
github.com/rogpeppe/go-internal v1.2.2 // indirect
github.com/rogpeppe/go-internal v1.2.2
github.com/spf13/cobra v0.0.3
github.com/spf13/pflag v1.0.3
github.com/spf13/viper v1.4.0
Expand Down
44 changes: 1 addition & 43 deletions pkg/kudoctl/cmd/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package cmd

import (
"fmt"
"strings"

"github.com/kudobuilder/kudo/pkg/kudoctl/cmd/install"
"github.com/pkg/errors"
Expand Down Expand Up @@ -32,47 +31,6 @@ var (
kubectl kudo install kafka --version=1.1.1`
)

// getParameterMap takes a slice of parameter strings, parses parameters into a map of keys and values
func getParameterMap(raw []string) (map[string]string, error) {
var errs []string
parameters := make(map[string]string)

for _, a := range raw {
key, value, err := parseParameter(a)
if err != nil {
errs = append(errs, *err)
continue
}
parameters[key] = value
}

if errs != nil {
return nil, errors.New(strings.Join(errs, ", "))
}

return parameters, nil
}

// parseParameter does all the parsing logic for an instance of a parameter provided to the command line
// it expects `=` as a delimiter as in key=value. It separates keys from values as a return. Any unexpected param will result in a
// detailed error message.
func parseParameter(raw string) (key string, param string, err *string) {

var errMsg string
s := strings.SplitN(raw, "=", 2)
if len(s) < 2 {
errMsg = fmt.Sprintf("parameter not set: %+v", raw)
} else if s[0] == "" {
errMsg = fmt.Sprintf("parameter name can not be empty: %+v", raw)
} else if s[1] == "" {
errMsg = fmt.Sprintf("parameter value can not be empty: %+v", raw)
}
if errMsg != "" {
return "", "", &errMsg
}
return s[0], s[1], nil
}

// newInstallCmd creates the install command for the CLI
func newInstallCmd() *cobra.Command {
options := install.DefaultOptions
Expand All @@ -85,7 +43,7 @@ func newInstallCmd() *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
// Prior to command execution we parse and validate passed parameters
var err error
options.Parameters, err = getParameterMap(parameters)
options.Parameters, err = install.GetParameterMap(parameters)
if err != nil {
return errors.WithMessage(err, "could not parse parameters")
}
Expand Down
17 changes: 9 additions & 8 deletions pkg/kudoctl/cmd/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,19 @@ func validate(args []string, options *Options) error {
return nil
}

// getPackageCRDs tries to look for package files resolving the operator name to:
// GetPackageCRDs tries to look for package files resolving the operator name to:
// - a local tar.gz file
// - a local directory
// - a url to a tar.gz
// - a operator name in the remote repository
// in that order. Should there exist a local folder e.g. `cassandra` it will take precedence
// over the remote repository package with the same name.
func getPackageCRDs(name string, options *Options, repository repo.Repository) (*bundle.PackageCRDs, error) {
func GetPackageCRDs(name string, version string, repository repo.Repository) (*bundle.PackageCRDs, error) {

// Local files/folder have priority
if _, err := os.Stat(name); err == nil {
f := finder.NewLocal()
b, err := f.GetBundle(name, options.PackageVersion)
b, err := f.GetBundle(name, version)
if err != nil {
return nil, err
}
Expand All @@ -70,14 +70,14 @@ func getPackageCRDs(name string, options *Options, repository repo.Repository) (

if http.IsValidURL(name) {
f := finder.NewURL()
b, err := f.GetBundle(name, options.PackageVersion)
b, err := f.GetBundle(name, version)
if err != nil {
return nil, err
}
return b.GetCRDs()
}

b, err := repository.GetBundle(name, options.PackageVersion)
b, err := repository.GetBundle(name, version)
if err != nil {
return nil, err
}
Expand All @@ -96,7 +96,7 @@ func installOperator(operatorArgument string, options *Options) error {
return errors.Wrap(err, "creating kudo client")
}

crds, err := getPackageCRDs(operatorArgument, options, repository)
crds, err := GetPackageCRDs(operatorArgument, options.PackageVersion, repository)
if err != nil {
return errors.Wrapf(err, "failed to resolve package CRDs for operator: %s", operatorArgument)
}
Expand Down Expand Up @@ -131,7 +131,7 @@ func installCrds(crds *bundle.PackageCRDs, kc *kudo.Client, options *Options) er
if err != nil {
return errors.Wrap(err, "retrieving existing operator versions")
}
if !versionExists(versionsInstalled, operatorVersion) {
if !VersionExists(versionsInstalled, operatorVersion) {
// this version does not exist in the cluster
if err := installSingleOperatorVersionToCluster(operatorName, options.Namespace, kc, crds.OperatorVersion); err != nil {
return errors.Wrapf(err, "installing OperatorVersion CRD for operator: %s", operatorName)
Expand Down Expand Up @@ -190,7 +190,8 @@ func validateCrds(crds *bundle.PackageCRDs, skipInstance bool) error {
return nil
}

func versionExists(versions []string, currentVersion string) bool {
// VersionExists looks for string version inside collection of versions
func VersionExists(versions []string, currentVersion string) bool {
for _, v := range versions {
if v == currentVersion {
return true
Expand Down
48 changes: 48 additions & 0 deletions pkg/kudoctl/cmd/install/params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package install

import (
"errors"
"fmt"
"strings"
)

// GetParameterMap takes a slice of parameter strings, parses parameters into a map of keys and values
func GetParameterMap(raw []string) (map[string]string, error) {
var errs []string
parameters := make(map[string]string)

for _, a := range raw {
key, value, err := parseParameter(a)
if err != nil {
errs = append(errs, *err)
continue
}
parameters[key] = value
}

if errs != nil {
return nil, errors.New(strings.Join(errs, ", "))
}

return parameters, nil
}

// parseParameter does all the parsing logic for an instance of a parameter provided to the command line
// it expects `=` as a delimiter as in key=value. It separates keys from values as a return. Any unexpected param will result in a
// detailed error message.
func parseParameter(raw string) (key string, param string, err *string) {

var errMsg string
s := strings.SplitN(raw, "=", 2)
if len(s) < 2 {
errMsg = fmt.Sprintf("parameter not set: %+v", raw)
} else if s[0] == "" {
errMsg = fmt.Sprintf("parameter name can not be empty: %+v", raw)
} else if s[1] == "" {
errMsg = fmt.Sprintf("parameter value can not be empty: %+v", raw)
}
if errMsg != "" {
return "", "", &errMsg
}
return s[0], s[1], nil
}
30 changes: 30 additions & 0 deletions pkg/kudoctl/cmd/install/params_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package install

import (
"testing"

"github.com/stretchr/testify/assert"
)

var parameterParsingTests = []struct {
paramStr string
key string
value string
err string
}{
{"foo", "", "", "parameter not set: foo"},
{"foo=", "", "", "parameter value can not be empty: foo="},
{"=bar", "", "", "parameter name can not be empty: =bar"},
{"foo=bar", "foo", "bar", ""},
}

func TestTableParameterParsing(t *testing.T) {
for _, test := range parameterParsingTests {
key, value, err := parseParameter(test.paramStr)
assert.Equal(t, key, test.key)
assert.Equal(t, value, test.value)
if err != nil {
assert.Equal(t, *err, test.err)
}
}
}
23 changes: 0 additions & 23 deletions pkg/kudoctl/cmd/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,26 +49,3 @@ func TestTableNewInstallCmd_WithParameters(t *testing.T) {
assert.NotNil(t, err, test.errorMessage)
}
}

var parameterParsingTests = []struct {
paramStr string
key string
value string
err string
}{
{"foo", "", "", "parameter not set: foo"},
{"foo=", "", "", "parameter value can not be empty: foo="},
{"=bar", "", "", "parameter name can not be empty: =bar"},
{"foo=bar", "foo", "bar", ""},
}

func TestTableParameterParsing(t *testing.T) {
for _, test := range parameterParsingTests {
key, value, err := parseParameter(test.paramStr)
assert.Equal(t, key, test.key)
assert.Equal(t, value, test.value)
if err != nil {
assert.Equal(t, *err, test.err)
}
}
}
1 change: 1 addition & 0 deletions pkg/kudoctl/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ and serves as an API aggregation layer.
}

cmd.AddCommand(newInstallCmd())
cmd.AddCommand(newUpgradeCmd())
cmd.AddCommand(newGetCmd())
cmd.AddCommand(newPlanCmd())
cmd.AddCommand(newTestCmd())
Expand Down
Loading

0 comments on commit 5e2dfd0

Please sign in to comment.