Skip to content

Commit

Permalink
allow values-override for install and upgrade api
Browse files Browse the repository at this point in the history
Author:    Dinesh Kumar <[email protected]>
Co-authored-by: Anirudh M <[email protected]>
Co-authored-by: ys.achinta <[email protected]>
  • Loading branch information
3 people committed Aug 6, 2020
1 parent 4753d46 commit d554e3e
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 46 deletions.
2 changes: 1 addition & 1 deletion pkg/api/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type InstallResponse struct {
Status string `json:"status,omitempty"`
}

// RODO: we could use interface as well if everything's in same package
// TODO: we could use interface as well if everything's in same package
func Install(svc Service) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

Expand Down
30 changes: 8 additions & 22 deletions pkg/api/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ type ReleaseConfig struct {
Name string
Namespace string
ChartName string
Version string
Install bool
}

type ChartValues map[string]interface{}
Expand All @@ -47,14 +49,6 @@ type ReleaseResult struct {
Status string
}

func (s Service) getValues(vals ChartValues) (ChartValues, error) {
// valueOpts := &values.Options{}
//valueOpts.Values = append(valueOpts.Values, vals)
//TODO: we need to make this as Provider, so it'll be able to merge
// why do we need getter.ALl?
return vals, nil
}

func (s Service) Install(ctx context.Context, cfg ReleaseConfig, values ChartValues) (*ReleaseResult, error) {
if err := s.validate(cfg, values); err != nil {
return nil, fmt.Errorf("error request validation: %v", err)
Expand All @@ -63,39 +57,32 @@ func (s Service) Install(ctx context.Context, cfg ReleaseConfig, values ChartVal
if err != nil {
return nil, err
}
vals, err := s.getValues(values)
if err != nil {
return nil, fmt.Errorf("error merging values: %v", err)
}
return s.installChart(cfg, chart, vals)

return s.installChart(cfg, chart, values)
}

func (s Service) Upgrade(ctx context.Context, cfg ReleaseConfig, values ChartValues) (*ReleaseResult, error) {
s.upgrader.SetConfig(cfg)
if err := s.validate(cfg, values); err != nil {
return nil, fmt.Errorf("error request validation: %v", err)
}
chart, err := s.loadChart(cfg.ChartName)
if err != nil {
return nil, err
}
vals, err := s.getValues(values)
if err != nil {
return nil, fmt.Errorf("error merging values: %v", err)
}

if s.upgrader.GetInstall() {
if _, err := s.history.Run(cfg.Name); err == driver.ErrReleaseNotFound {
logger.Debugf("release %q does not exist. Installing it now.\n", cfg.Name)
return s.installChart(cfg, chart, vals)
return s.installChart(cfg, chart, values)
}
}

return s.upgradeRelease(cfg, chart, vals)
return s.upgradeRelease(cfg, chart, values)
}

func (s Service) loadChart(chartName string) (*chart.Chart, error) {
logger.Debugf("[install/upgrade] chart name: %s", chartName)
cp, err := s.chartloader.LocateChart(chartName, s.settings)
cp, err := s.LocateChart(chartName, s.settings)
if err != nil {
return nil, fmt.Errorf("error in locating chart: %v", err)
}
Expand All @@ -120,7 +107,6 @@ func (s Service) installChart(icfg ReleaseConfig, ch *chart.Chart, vals ChartVal
}

func (s Service) upgradeRelease(ucfg ReleaseConfig, ch *chart.Chart, vals ChartValues) (*ReleaseResult, error) {
s.upgrader.SetConfig(ucfg)
release, err := s.upgrader.Run(ucfg.Name, ch, vals)
if err != nil {
return nil, fmt.Errorf("error in upgrading chart: %v", err)
Expand Down
20 changes: 10 additions & 10 deletions pkg/api/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func (s *ServiceTestSuite) TestInstallShouldReturnErrorOnLocalChartReference() {

func (s *ServiceTestSuite) TestInstallShouldReturnErrorOnFailedInstallRun() {
var release *release.Release
var vals map[string]interface{}
vals := map[string]interface{}{}
chartName := "stable/valid-chart"
cfg := api.ReleaseConfig{
Name: "some-component",
Expand All @@ -110,7 +110,7 @@ func (s *ServiceTestSuite) TestInstallShouldReturnErrorOnFailedInstallRun() {
}

func (s *ServiceTestSuite) TestInstallShouldReturnResultOnSuccess() {
var vals map[string]interface{}
vals := map[string]interface{}{}
chartName := "stable/valid-chart"
cfg := api.ReleaseConfig{
Name: "some-component",
Expand All @@ -134,18 +134,18 @@ func (s *ServiceTestSuite) TestInstallShouldReturnResultOnSuccess() {
}

func (s *ServiceTestSuite) TestUpgradeInstallTrueShouldInstallChart() {
var vals map[string]interface{}
vals := map[string]interface{}{}
chartName := "stable/valid-chart"
cfg := api.ReleaseConfig{
Name: "some-component",
Namespace: "hermes",
ChartName: chartName,
}

s.upgrader.On("SetConfig", cfg)
s.chartloader.On("LocateChart", chartName, s.settings).Return("testdata/albatross", nil)
s.upgrader.On("GetInstall").Return(true)
s.history.On("Run", "some-component").Return([]*release.Release{}, driver.ErrReleaseNotFound)
s.installer.On("SetConfig", cfg)
s.history.On("Run", "some-component").Return([]*release.Release{}, driver.ErrReleaseNotFound)
release := &release.Release{Name: "some-comp-release", Info: &release.Info{Status: release.StatusDeployed}}
s.installer.On("Run", mock.AnythingOfType("*chart.Chart"), vals).Return(release, nil)

Expand All @@ -169,7 +169,7 @@ func (s *ServiceTestSuite) TestUpgradeInstallFalseShouldNotInstallChart() {
Namespace: "hermes",
ChartName: chartName,
}
var vals map[string]interface{}
vals := map[string]interface{}{}
s.chartloader.On("LocateChart", chartName, s.settings).Return("testdata/albatross", nil)
s.upgrader.On("GetInstall").Return(false)
s.upgrader.On("SetConfig", cfg)
Expand All @@ -195,7 +195,7 @@ func (s *ServiceTestSuite) TestUpgradeShouldReturnErrorOnFailedUpgradeRun() {
Namespace: "hermes",
ChartName: chartName,
}
var vals map[string]interface{}
vals := map[string]interface{}{}
s.chartloader.On("LocateChart", chartName, s.settings).Return("testdata/albatross", nil)
s.upgrader.On("GetInstall").Return(false)
s.upgrader.On("SetConfig", cfg)
Expand All @@ -218,7 +218,7 @@ func (s *ServiceTestSuite) TestUpgradeShouldReturnResultOnSuccess() {
Namespace: "hermes",
ChartName: chartName,
}
var vals map[string]interface{}
vals := map[string]interface{}{}
s.chartloader.On("LocateChart", chartName, s.settings).Return("testdata/albatross", nil)
s.upgrader.On("GetInstall").Return(false)
s.upgrader.On("SetConfig", cfg)
Expand All @@ -243,7 +243,7 @@ func (s *ServiceTestSuite) TestUpgradeValidateFailShouldResultFailure() {
Namespace: "hermes",
ChartName: chartName,
}

s.upgrader.On("SetConfig", cfg)
res, err := s.svc.Upgrade(s.ctx, cfg, vals)

t := s.T()
Expand All @@ -263,7 +263,7 @@ func (s *ServiceTestSuite) TestUpgradeShouldReturnErrorOnInvalidChart() {
}
var vals api.ChartValues
s.chartloader.On("LocateChart", chartName, s.settings).Return("", errors.New("Unable to find chart"))

s.upgrader.On("SetConfig", cfg)
res, err := s.svc.Upgrade(s.ctx, cfg, vals)

t := s.T()
Expand Down
27 changes: 22 additions & 5 deletions pkg/api/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ type UpgradeRequest struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
Chart string `json:"chart"`
Values map[string]interface{} `json:"values"`
Values map[string]interface{} `json:"values,omitempty"`
Flags map[string]interface{} `json:"flags,omitempty"`
}

type UpgradeResponse struct {
Expand All @@ -23,18 +24,34 @@ type UpgradeResponse struct {
func Upgrade(svc Service) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()

var req UpgradeRequest

if err := json.NewDecoder(r.Body).Decode(&req); err == io.EOF || err != nil {
logger.Errorf("[Upgrade] error decoding request: %v", err.Error())
w.WriteHeader(http.StatusBadRequest)
logger.Errorf("[Upgrade] error decoding request: %v", err)
return
}

defer r.Body.Close()

var install bool
var version string
for key, value := range req.Flags {
if key == "install" {
install = value.(bool)
}
if key == "version" {
version = value.(string)
}
}

if version == "" {
logger.Debugf("setting version to >0.0.0-0")
version = ">0.0.0-0"
}

var response UpgradeResponse
cfg := ReleaseConfig{ChartName: req.Chart, Name: req.Name, Namespace: req.Namespace}
cfg := ReleaseConfig{ChartName: req.Chart, Name: req.Name, Namespace: req.Namespace, Version: version, Install: install}

res, err := svc.Upgrade(r.Context(), cfg, req.Values)
if err != nil {
respondUpgradeError(w, "error while upgrading chart: %v", err)
Expand Down
26 changes: 18 additions & 8 deletions pkg/api/upgrade_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,22 @@ func (s *UpgradeTestSuite) SetupTest() {
func (s *UpgradeTestSuite) TestShouldReturnDeployedStatusOnSuccessfulUpgrade() {
chartName := "stable/redis-ha"
body := fmt.Sprintf(`{
"chart":"%s",
"name": "redis-v5",
"namespace": "something"}`, chartName)
"chart":"%s",
"name": "redis-v5",
"flags": {
"install": false
},
"values": {
"usePassword": false
},
"namespace": "something"}`, chartName)
req, _ := http.NewRequest("POST", fmt.Sprintf("%s/upgrade", s.server.URL), strings.NewReader(body))
s.mockChartLoader.On("LocateChart", chartName, s.appConfig).Return("./testdata/albatross", nil)
ucfg := api.ReleaseConfig{ChartName: chartName, Name: "redis-v5", Namespace: "something"}
ucfg := api.ReleaseConfig{ChartName: chartName, Name: "redis-v5", Namespace: "something", Version: ">0.0.0-0"}
s.mockUpgrader.On("GetInstall").Return(false)
s.mockUpgrader.On("SetConfig", ucfg)
release := &release.Release{Info: &release.Info{Status: release.StatusDeployed}}
var vals map[string]interface{}
vals := map[string]interface{}{"usePassword": false}
//TODO: pass chart object and verify values present testdata chart yml
s.mockUpgrader.On("Run", "redis-v5", mock.AnythingOfType("*chart.Chart"), vals).Return(release, nil)

Expand All @@ -69,8 +75,6 @@ func (s *UpgradeTestSuite) TestShouldReturnDeployedStatusOnSuccessfulUpgrade() {
assert.Equal(s.T(), http.StatusOK, resp.StatusCode)
expectedResponse := `{"status":"deployed"}` + "\n"
respBody, _ := ioutil.ReadAll(resp.Body)
fmt.Println(expectedResponse)
fmt.Println(respBody)

assert.Equal(s.T(), expectedResponse, string(respBody))
require.NoError(s.T(), err)
Expand All @@ -82,9 +86,15 @@ func (s *UpgradeTestSuite) TestShouldReturnInternalServerErrorOnFailure() {
chartName := "stable/redis-ha"
body := fmt.Sprintf(`{
"chart":"%s",
"name": "redis-v5",
"name": "redis-v5",
"flags": {
"install": true,
"version": "7.5.4"
},
"namespace": "something"}`, chartName)
req, _ := http.NewRequest("POST", fmt.Sprintf("%s/install", s.server.URL), strings.NewReader(body))
ucfg := api.ReleaseConfig{ChartName: chartName, Name: "redis-v5", Namespace: "something", Version: "7.5.4", Install: true}
s.mockUpgrader.On("SetConfig", ucfg)
s.mockChartLoader.On("LocateChart", chartName, s.appConfig).Return("./testdata/albatross", errors.New("Invalid chart"))

resp, err := http.DefaultClient.Do(req)
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/upgrader.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ type historyrunner interface {

func (u *Upgrader) SetConfig(cfg ReleaseConfig) {
u.Namespace = cfg.Namespace
u.ChartPathOptions.Version = cfg.Version
u.Install = cfg.Install
}

func (u *Upgrader) GetInstall() bool {
Expand Down

0 comments on commit d554e3e

Please sign in to comment.