Skip to content

Commit

Permalink
Refactor install api with service
Browse files Browse the repository at this point in the history
  • Loading branch information
devdinu authored and kaustubhkurve committed Aug 6, 2020
1 parent 618e420 commit 8a940fa
Show file tree
Hide file tree
Showing 13 changed files with 294 additions and 221 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
_dist/
bin/
vendor/
*.swp
10 changes: 6 additions & 4 deletions cmd/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import (
"fmt"
"net/http"

"helm.sh/helm/v3/pkg/http/api/install"
"helm.sh/helm/v3/pkg/http/api"
"helm.sh/helm/v3/pkg/http/api/list"
"helm.sh/helm/v3/pkg/http/api/ping"
"helm.sh/helm/v3/pkg/http/api/upgrade"
"helm.sh/helm/v3/pkg/servercontext"
)

Expand All @@ -18,10 +17,13 @@ func main() {

func startServer(appconfig *servercontext.Application) {
router := http.NewServeMux()
//TODO: use gorilla mux and add middleware to write content type and other headers
cfg := servercontext.App().Config
service := api.NewService(cfg)
router.Handle("/ping", ping.Handler())
router.Handle("/list", list.Handler())
router.Handle("/install", install.Handler())
router.Handle("/upgrade", upgrade.Handler())
router.Handle("/install", api.Install(service))
router.Handle("/upgrade", api.Upgrade(service))

err := http.ListenAndServe(fmt.Sprintf(":%d", 8080), router)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ require (
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.1.0
github.com/xenolf/lego v0.3.2-0.20160613233155-a9d8cec0e656 // indirect
go.uber.org/zap v1.10.0
golang.org/x/crypto v0.0.0-20191028145041-f83a4685e152
golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271 // indirect
golang.org/x/sys v0.0.0-20191028164358-195ce5e7f934 // indirect
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -506,8 +506,11 @@ go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
Expand Down
47 changes: 47 additions & 0 deletions pkg/http/api/install.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package api

import (
"encoding/json"
"net/http"

"helm.sh/helm/v3/pkg/http/api/logger"
)

type InstallRequest struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
Chart string `json:"chart"`
Values map[string]interface{} `json:"values"`
}

type InstallResponse struct {
Error string `json:"error,omitempty"`
Status string
}

// RODO: 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) {

var req InstallRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
logger.Errorf("[Install] error decoding request: %v", err)
w.WriteHeader(http.StatusBadRequest)
return
}
defer r.Body.Close()
var response InstallResponse
res, err := svc.Install(r.Context(), req.Chart, req.Values)
if err != nil {
response.Error = err.Error()
logger.Errorf("[Install] error while installing chart: %v", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
response.Status = res.status
if err := json.NewEncoder(w).Encode(response); err != nil {
logger.Errorf("[Install] error writing response %v", err)
return
}
})
}
14 changes: 0 additions & 14 deletions pkg/http/api/install/installcontract.go

This file was deleted.

85 changes: 0 additions & 85 deletions pkg/http/api/install/installhandler.go

This file was deleted.

40 changes: 40 additions & 0 deletions pkg/http/api/logger/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package logger

import (
"go.uber.org/zap"
)

var log *zap.SugaredLogger

func Debugf(fmt string, args ...interface{}) {
log.Debugf(fmt, args...)
}

func Fatalf(fmt string, args ...interface{}) {
log.Fatalf(fmt, args...)
}

func Errorf(fmt string, args ...interface{}) {
log.Errorf(fmt, args...)
}

func Infof(fmt string, args ...interface{}) {
log.Infof(fmt, args...)
}

func Setup(level string) {
//TODO: map from env config
var zlog *zap.Logger
switch level {
case "debug":
zlog, _ = zap.NewDevelopment()
case "none":
zlog = zap.NewNop()
default:
zlog, _ = zap.NewProduction()
}
// This condition is to avoid race conditions in test cases
if log == nil {
log = zlog.Sugar()
}
}
71 changes: 71 additions & 0 deletions pkg/http/api/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package api

import (
"context"
"fmt"

"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/cli/values"
"helm.sh/helm/v3/pkg/getter"
"helm.sh/helm/v3/pkg/servercontext"
)

type Service struct {
config *cli.EnvSettings
install *action.Install
}

type chartValues map[string]interface{}

type installResult struct {
status string
}

func (s Service) getValues(vals chartValues) (chartValues, error) {
valueOpts := &values.Options{}
//valueOpts.Values = append(valueOpts.Values, vals)
return valueOpts.MergeValues(getter.All(servercontext.App().Config))
}

func (s Service) Install(ctx context.Context, chartName string, values chartValues) (installResult, error) {
var result installResult
chart, err := s.loadChart(chartName)
if err != nil {
return result, err
}
vals, err := s.getValues(values)
if err != nil {
return result, fmt.Errorf("error merging values: %v", err)
}
release, err := s.install.Run(chart, vals)
if err != nil {
return result, fmt.Errorf("error in installing chart: %v", err)
}
if release.Info != nil {
result.status = release.Info.Status.String()
}
return result, nil
}

func (s Service) loadChart(chartName string) (*chart.Chart, error) {
cp, err := s.install.ChartPathOptions.LocateChart(chartName, s.config)
if err != nil {
return nil, fmt.Errorf("error in locating chart: %v", err)
}
var requestedChart *chart.Chart
if requestedChart, err = loader.Load(cp); err != nil {
return nil, fmt.Errorf("error loading chart: %v", err)
}
return requestedChart, nil
}

func NewService(cfg *cli.EnvSettings) Service {
return Service{
config: cfg,
//TODO: not sure why this's needed, but we can refactor later,could be passed as param
install: action.NewInstall(servercontext.App().ActionConfig),
}
}
Loading

0 comments on commit 8a940fa

Please sign in to comment.