Skip to content

Commit

Permalink
Add Helm 3 UpgradeRelease (#1421)
Browse files Browse the repository at this point in the history
* Add Helm 3 UpgradeRelease

* Rename v1 support constant

* Add TODO comment in switch statement
  • Loading branch information
SimonAlling authored and Andres Martinez Gotor committed Jan 9, 2020
1 parent 1fe73e3 commit a7f9b5e
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 2 deletions.
34 changes: 32 additions & 2 deletions cmd/kubeops/internal/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const (
nameParam = "releaseName"
)

const isV1SupportRequired = false

// This type represents the fact that a regular handler cannot actually be created until we have access to the request,
// because a valid action config (and hence agent config) cannot be created until then.
// If the agent config were a "this" argument instead of an explicit argument, it would be easy to create a handler with a "zero" config.
Expand Down Expand Up @@ -91,8 +93,7 @@ func ListAllReleases(cfg agent.Config, w http.ResponseWriter, req *http.Request,
}

func CreateRelease(cfg agent.Config, w http.ResponseWriter, req *http.Request, params handlerutil.Params) {
requireV1Support := false
chartDetails, chartMulti, err := handlerutil.ParseAndGetChart(req, cfg.ChartClient, requireV1Support)
chartDetails, chartMulti, err := handlerutil.ParseAndGetChart(req, cfg.ChartClient, isV1SupportRequired)
if err != nil {
response.NewErrorResponse(handlerutil.ErrorCode(err), err.Error()).Write(w)
return
Expand All @@ -109,6 +110,35 @@ func CreateRelease(cfg agent.Config, w http.ResponseWriter, req *http.Request, p
response.NewDataResponse(release).Write(w)
}

// OperateRelease decides which method to call depending on the "action" query param.
func OperateRelease(cfg agent.Config, w http.ResponseWriter, req *http.Request, params handlerutil.Params) {
switch req.FormValue("action") {
case "upgrade":
upgradeRelease(cfg, w, req, params)
// TODO: Add "rollback" and "test" cases here.
default:
// By default, for maintaining compatibility, we call upgrade.
upgradeRelease(cfg, w, req, params)
}
}

func upgradeRelease(cfg agent.Config, w http.ResponseWriter, req *http.Request, params handlerutil.Params) {
releaseName := params[nameParam]
chartDetails, chartMulti, err := handlerutil.ParseAndGetChart(req, cfg.ChartClient, isV1SupportRequired)
if err != nil {
response.NewErrorResponse(handlerutil.ErrorCode(err), err.Error()).Write(w)
return
}
ch := chartMulti.Helm3Chart
rel, err := agent.UpgradeRelease(cfg.ActionConfig, releaseName, chartDetails.Values, ch)
if err != nil {
response.NewErrorResponse(handlerutil.ErrorCode(err), err.Error()).Write(w)
return
}
response.NewDataResponse(newDashboardCompatibleRelease(*rel)).Write(w)

}

func GetRelease(cfg agent.Config, w http.ResponseWriter, req *http.Request, params handlerutil.Params) {
// Namespace is already known by the RESTClientGetter.
releaseName := params[nameParam]
Expand Down
3 changes: 3 additions & 0 deletions cmd/kubeops/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ func main() {
apiv1.Methods("GET").Path("/namespaces/{namespace}/releases/{releaseName}").Handler(negroni.New(
negroni.Wrap(withAgentConfig(handler.GetRelease)),
))
apiv1.Methods("PUT").Path("/namespaces/{namespace}/releases/{releaseName}").Handler(negroni.New(
negroni.Wrap(withAgentConfig(handler.OperateRelease)),
))
apiv1.Methods("DELETE").Path("/namespaces/{namespace}/releases/{releaseName}").Handler(negroni.New(
negroni.Wrap(withAgentConfig(handler.DeleteRelease)),
))
Expand Down
21 changes: 21 additions & 0 deletions pkg/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ package agent

import (
"errors"
"fmt"
"strconv"

chartUtils "github.com/kubeapps/kubeapps/pkg/chart"
"github.com/kubeapps/kubeapps/pkg/proxy"
log "github.com/sirupsen/logrus"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/kube"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v3/pkg/storage"
Expand Down Expand Up @@ -89,6 +91,25 @@ func CreateRelease(config Config, name, namespace, valueString string, ch *chart
return release, nil
}

func UpgradeRelease(actionConfig *action.Configuration, name, valuesYaml string, ch *chart.Chart) (*release.Release, error) {
// Check if the release already exists:
_, err := GetRelease(actionConfig, name)
if err != nil {
return nil, err
}
log.Printf("Upgrading release %s", name)
cmd := action.NewUpgrade(actionConfig)
values, err := chartutil.ReadValues([]byte(valuesYaml))
if err != nil {
return nil, fmt.Errorf("Unable to upgrade the release because values could not be parsed: %v", err)
}
res, err := cmd.Run(name, ch, values)
if err != nil {
return nil, fmt.Errorf("Unable to upgrade the release: %v", err)
}
return res, nil
}

func GetRelease(actionConfig *action.Configuration, name string) (*release.Release, error) {
// Namespace is already known by the RESTClientGetter.
cmd := action.NewGet(actionConfig)
Expand Down

0 comments on commit a7f9b5e

Please sign in to comment.