瀏覽代碼

cleanup of chart handler

Alexander Belanger 5 年之前
父節點
當前提交
f15eb6536e
共有 3 個文件被更改,包括 110 次插入145 次删除
  1. 1 4
      internal/forms/chart.go
  2. 108 140
      server/api/chart_handler.go
  3. 1 1
      server/router/router.go

+ 1 - 4
internal/forms/chart.go

@@ -50,11 +50,8 @@ type ListChartForm struct {
 }
 }
 
 
 // PopulateListFromQueryParams populates fields in the ListChartForm using the passed
 // PopulateListFromQueryParams populates fields in the ListChartForm using the passed
-// url.Values (the parsed query params). It calls the underlying
-// PopulateHelmOptionsFromQueryParams
+// url.Values (the parsed query params)
 func (lcf *ListChartForm) PopulateListFromQueryParams(vals url.Values) {
 func (lcf *ListChartForm) PopulateListFromQueryParams(vals url.Values) {
-	lcf.ChartForm.PopulateHelmOptionsFromQueryParams(vals)
-
 	if namespace, ok := vals["namespace"]; ok && len(namespace) == 1 {
 	if namespace, ok := vals["namespace"]; ok && len(namespace) == 1 {
 		lcf.ListFilter.Namespace = namespace[0]
 		lcf.ListFilter.Namespace = namespace[0]
 	}
 	}

+ 108 - 140
server/api/chart_handler.go

@@ -15,56 +15,36 @@ import (
 const (
 const (
 	ErrChartDecode ErrorCode = iota + 600
 	ErrChartDecode ErrorCode = iota + 600
 	ErrChartValidateFields
 	ErrChartValidateFields
+	ErrChartReadData
 )
 )
 
 
-// HandleListCharts retrieves a list of charts with various filter options
-func (app *App) HandleListCharts(w http.ResponseWriter, r *http.Request) {
-	session, err := app.store.Get(r, app.cookieName)
-
-	if err != nil {
-		app.handleErrorFormDecoding(err, ErrChartDecode, w)
-		return
-	}
-
-	vals, err := url.ParseQuery(r.URL.RawQuery)
-
-	if err != nil {
-		app.handleErrorFormDecoding(err, ErrChartDecode, w)
-		return
-	}
-
-	// get the filter options
+// HandleListReleases retrieves a list of releases for a cluster
+// with various filter options
+func (app *App) HandleListReleases(w http.ResponseWriter, r *http.Request) {
 	form := &forms.ListChartForm{
 	form := &forms.ListChartForm{
 		ChartForm: &forms.ChartForm{
 		ChartForm: &forms.ChartForm{
 			Form: &helm.Form{},
 			Form: &helm.Form{},
 		},
 		},
 		ListFilter: &helm.ListFilter{},
 		ListFilter: &helm.ListFilter{},
 	}
 	}
-	form.PopulateListFromQueryParams(vals)
 
 
-	if sessID, ok := session.Values["user_id"].(uint); ok {
-		form.PopulateHelmOptionsFromUserID(sessID, app.repo.User)
-	}
+	agent, err := app.getAgentFromQueryParams(
+		w,
+		r,
+		form.ChartForm,
+		form.ChartForm.PopulateHelmOptionsFromQueryParams,
+		form.PopulateListFromQueryParams,
+	)
 
 
-	// validate the form
-	if err := app.validator.Struct(form); err != nil {
-		app.handleErrorFormValidation(err, ErrChartValidateFields, w)
+	// errors are handled in app.getAgentFromQueryParams
+	if err != nil {
 		return
 		return
 	}
 	}
 
 
-	// create a new agent
-	var agent *helm.Agent
-
-	if app.testing {
-		agent = app.TestAgents.HelmAgent
-	} else {
-		agent, err = helm.GetAgentOutOfClusterConfig(form.ChartForm.Form, app.logger)
-	}
-
 	releases, err := agent.ListReleases(form.Namespace, form.ListFilter)
 	releases, err := agent.ListReleases(form.Namespace, form.ListFilter)
 
 
 	if err != nil {
 	if err != nil {
-		app.handleErrorFormValidation(err, ErrChartValidateFields, w)
+		app.handleErrorRead(err, ErrChartReadData, w)
 		return
 		return
 	}
 	}
 
 
@@ -76,17 +56,9 @@ func (app *App) HandleListCharts(w http.ResponseWriter, r *http.Request) {
 
 
 // HandleGetChart retrieves a single chart based on a name and revision
 // HandleGetChart retrieves a single chart based on a name and revision
 func (app *App) HandleGetChart(w http.ResponseWriter, r *http.Request) {
 func (app *App) HandleGetChart(w http.ResponseWriter, r *http.Request) {
-	session, err := app.store.Get(r, app.cookieName)
-
-	if err != nil {
-		app.handleErrorFormDecoding(err, ErrChartDecode, w)
-		return
-	}
-
 	name := chi.URLParam(r, "name")
 	name := chi.URLParam(r, "name")
 	revision, err := strconv.ParseUint(chi.URLParam(r, "revision"), 0, 64)
 	revision, err := strconv.ParseUint(chi.URLParam(r, "revision"), 0, 64)
 
 
-	// get the filter options
 	form := &forms.GetChartForm{
 	form := &forms.GetChartForm{
 		ChartForm: &forms.ChartForm{
 		ChartForm: &forms.ChartForm{
 			Form: &helm.Form{},
 			Form: &helm.Form{},
@@ -95,38 +67,22 @@ func (app *App) HandleGetChart(w http.ResponseWriter, r *http.Request) {
 		Revision: int(revision),
 		Revision: int(revision),
 	}
 	}
 
 
-	vals, err := url.ParseQuery(r.URL.RawQuery)
+	agent, err := app.getAgentFromQueryParams(
+		w,
+		r,
+		form.ChartForm,
+		form.ChartForm.PopulateHelmOptionsFromQueryParams,
+	)
 
 
+	// errors are handled in app.getAgentFromQueryParams
 	if err != nil {
 	if err != nil {
-		app.handleErrorFormDecoding(err, ErrChartDecode, w)
 		return
 		return
 	}
 	}
 
 
-	form.PopulateHelmOptionsFromQueryParams(vals)
-
-	if sessID, ok := session.Values["user_id"].(uint); ok {
-		form.PopulateHelmOptionsFromUserID(sessID, app.repo.User)
-	}
-
-	// validate the form
-	if err := app.validator.Struct(form); err != nil {
-		app.handleErrorFormValidation(err, ErrChartValidateFields, w)
-		return
-	}
-
-	// create a new agent
-	var agent *helm.Agent
-
-	if app.testing {
-		agent = app.TestAgents.HelmAgent
-	} else {
-		agent, err = helm.GetAgentOutOfClusterConfig(form.ChartForm.Form, app.logger)
-	}
-
 	release, err := agent.GetRelease(form.Name, form.Revision)
 	release, err := agent.GetRelease(form.Name, form.Revision)
 
 
 	if err != nil {
 	if err != nil {
-		app.handleErrorFormValidation(err, ErrChartValidateFields, w)
+		app.handleErrorRead(err, ErrChartReadData, w)
 		return
 		return
 	}
 	}
 
 
@@ -138,16 +94,8 @@ func (app *App) HandleGetChart(w http.ResponseWriter, r *http.Request) {
 
 
 // HandleListChartHistory retrieves a history of charts based on a chart name
 // HandleListChartHistory retrieves a history of charts based on a chart name
 func (app *App) HandleListChartHistory(w http.ResponseWriter, r *http.Request) {
 func (app *App) HandleListChartHistory(w http.ResponseWriter, r *http.Request) {
-	session, err := app.store.Get(r, app.cookieName)
-
-	if err != nil {
-		app.handleErrorFormDecoding(err, ErrChartDecode, w)
-		return
-	}
-
 	name := chi.URLParam(r, "name")
 	name := chi.URLParam(r, "name")
 
 
-	// get the filter options
 	form := &forms.ListChartHistoryForm{
 	form := &forms.ListChartHistoryForm{
 		ChartForm: &forms.ChartForm{
 		ChartForm: &forms.ChartForm{
 			Form: &helm.Form{},
 			Form: &helm.Form{},
@@ -155,34 +103,18 @@ func (app *App) HandleListChartHistory(w http.ResponseWriter, r *http.Request) {
 		Name: name,
 		Name: name,
 	}
 	}
 
 
-	vals, err := url.ParseQuery(r.URL.RawQuery)
+	agent, err := app.getAgentFromQueryParams(
+		w,
+		r,
+		form.ChartForm,
+		form.ChartForm.PopulateHelmOptionsFromQueryParams,
+	)
 
 
+	// errors are handled in app.getAgentFromQueryParams
 	if err != nil {
 	if err != nil {
-		app.handleErrorFormDecoding(err, ErrChartDecode, w)
-		return
-	}
-
-	form.PopulateHelmOptionsFromQueryParams(vals)
-
-	if sessID, ok := session.Values["user_id"].(uint); ok {
-		form.PopulateHelmOptionsFromUserID(sessID, app.repo.User)
-	}
-
-	// validate the form
-	if err := app.validator.Struct(form); err != nil {
-		app.handleErrorFormValidation(err, ErrChartValidateFields, w)
 		return
 		return
 	}
 	}
 
 
-	// create a new agent
-	var agent *helm.Agent
-
-	if app.testing {
-		agent = app.TestAgents.HelmAgent
-	} else {
-		agent, err = helm.GetAgentOutOfClusterConfig(form.ChartForm.Form, app.logger)
-	}
-
 	release, err := agent.GetReleaseHistory(form.Name)
 	release, err := agent.GetReleaseHistory(form.Name)
 
 
 	if err != nil {
 	if err != nil {
@@ -198,16 +130,8 @@ func (app *App) HandleListChartHistory(w http.ResponseWriter, r *http.Request) {
 
 
 // HandleUpgradeChart upgrades a chart with new values.yaml
 // HandleUpgradeChart upgrades a chart with new values.yaml
 func (app *App) HandleUpgradeChart(w http.ResponseWriter, r *http.Request) {
 func (app *App) HandleUpgradeChart(w http.ResponseWriter, r *http.Request) {
-	session, err := app.store.Get(r, app.cookieName)
-
-	if err != nil {
-		app.handleErrorFormDecoding(err, ErrChartDecode, w)
-		return
-	}
-
 	name := chi.URLParam(r, "name")
 	name := chi.URLParam(r, "name")
 
 
-	// get the filter options
 	form := &forms.UpgradeChartForm{
 	form := &forms.UpgradeChartForm{
 		ChartForm: &forms.ChartForm{
 		ChartForm: &forms.ChartForm{
 			Form: &helm.Form{},
 			Form: &helm.Form{},
@@ -215,31 +139,22 @@ func (app *App) HandleUpgradeChart(w http.ResponseWriter, r *http.Request) {
 		Name: name,
 		Name: name,
 	}
 	}
 
 
-	// decode from JSON to form value
 	if err := json.NewDecoder(r.Body).Decode(form); err != nil {
 	if err := json.NewDecoder(r.Body).Decode(form); err != nil {
 		app.handleErrorFormDecoding(err, ErrUserDecode, w)
 		app.handleErrorFormDecoding(err, ErrUserDecode, w)
 		return
 		return
 	}
 	}
 
 
-	if sessID, ok := session.Values["user_id"].(uint); ok {
-		form.PopulateHelmOptionsFromUserID(sessID, app.repo.User)
-	}
+	agent, err := app.getAgentFromChartForm(
+		w,
+		r,
+		form.ChartForm,
+	)
 
 
-	// validate the form
-	if err := app.validator.Struct(form); err != nil {
-		app.handleErrorFormValidation(err, ErrChartValidateFields, w)
+	// errors are handled in app.getAgentFromBodyParams
+	if err != nil {
 		return
 		return
 	}
 	}
 
 
-	// create a new agent
-	var agent *helm.Agent
-
-	if app.testing {
-		agent = app.TestAgents.HelmAgent
-	} else {
-		agent, err = helm.GetAgentOutOfClusterConfig(form.ChartForm.Form, app.logger)
-	}
-
 	_, err = agent.UpgradeChart(form.Name, form.Values)
 	_, err = agent.UpgradeChart(form.Name, form.Values)
 
 
 	if err != nil {
 	if err != nil {
@@ -252,18 +167,15 @@ func (app *App) HandleUpgradeChart(w http.ResponseWriter, r *http.Request) {
 
 
 // HandleRollbackChart rolls a release back to a specified revision
 // HandleRollbackChart rolls a release back to a specified revision
 func (app *App) HandleRollbackChart(w http.ResponseWriter, r *http.Request) {
 func (app *App) HandleRollbackChart(w http.ResponseWriter, r *http.Request) {
-	session, err := app.store.Get(r, app.cookieName)
+	name := chi.URLParam(r, "name")
+	revision, err := strconv.ParseUint(chi.URLParam(r, "revision"), 0, 64)
 
 
 	if err != nil {
 	if err != nil {
 		app.handleErrorFormDecoding(err, ErrChartDecode, w)
 		app.handleErrorFormDecoding(err, ErrChartDecode, w)
 		return
 		return
 	}
 	}
 
 
-	name := chi.URLParam(r, "name")
-	revision, err := strconv.ParseUint(chi.URLParam(r, "revision"), 0, 64)
-
-	// get the filter options
-	form := &forms.GetChartForm{
+	form := &forms.RollbackChartForm{
 		ChartForm: &forms.ChartForm{
 		ChartForm: &forms.ChartForm{
 			Form: &helm.Form{},
 			Form: &helm.Form{},
 		},
 		},
@@ -271,20 +183,83 @@ func (app *App) HandleRollbackChart(w http.ResponseWriter, r *http.Request) {
 		Revision: int(revision),
 		Revision: int(revision),
 	}
 	}
 
 
-	// decode from JSON to form value
 	if err := json.NewDecoder(r.Body).Decode(form); err != nil {
 	if err := json.NewDecoder(r.Body).Decode(form); err != nil {
 		app.handleErrorFormDecoding(err, ErrUserDecode, w)
 		app.handleErrorFormDecoding(err, ErrUserDecode, w)
 		return
 		return
 	}
 	}
 
 
-	if sessID, ok := session.Values["user_id"].(uint); ok {
-		form.PopulateHelmOptionsFromUserID(sessID, app.repo.User)
+	agent, err := app.getAgentFromChartForm(
+		w,
+		r,
+		form.ChartForm,
+	)
+
+	// errors are handled in app.getAgentFromBodyParams
+	if err != nil {
+		return
+	}
+
+	err = agent.RollbackRelease(form.Name, form.Revision)
+
+	if err != nil {
+		app.handleErrorInternal(err, w)
+		return
+	}
+
+	w.WriteHeader(http.StatusOK)
+}
+
+// ------------------------ Release handler helper functions ------------------------ //
+
+// getAgentFromQueryParams uses the query params to populate a form, and then
+// passes that form to the underlying app.getAgentFromChartForm to create a new
+// Helm agent.
+func (app *App) getAgentFromQueryParams(
+	w http.ResponseWriter,
+	r *http.Request,
+	form *forms.ChartForm,
+	// populate uses the query params to populate a form
+	populate ...func(vals url.Values),
+) (*helm.Agent, error) {
+	vals, err := url.ParseQuery(r.URL.RawQuery)
+
+	if err != nil {
+		app.handleErrorFormDecoding(err, ErrChartDecode, w)
+		return nil, err
+	}
+
+	for _, f := range populate {
+		f(vals)
+	}
+
+	return app.getAgentFromChartForm(w, r, form)
+}
+
+// getAgentFromChartForm uses a non-validated form to construct a new Helm agent based on
+// the userID found in the session and the options required by the Helm agent.
+func (app *App) getAgentFromChartForm(
+	w http.ResponseWriter,
+	r *http.Request,
+	form *forms.ChartForm,
+) (*helm.Agent, error) {
+	// read the session in order to generate the Helm agent
+	session, err := app.store.Get(r, app.cookieName)
+
+	// since we have already authenticated the user, throw a data read error if the session
+	// cannot be found
+	if err != nil {
+		app.handleErrorDataRead(err, w)
+		return nil, err
+	}
+
+	if userID, ok := session.Values["user_id"].(uint); ok {
+		form.PopulateHelmOptionsFromUserID(userID, app.repo.User)
 	}
 	}
 
 
 	// validate the form
 	// validate the form
 	if err := app.validator.Struct(form); err != nil {
 	if err := app.validator.Struct(form); err != nil {
 		app.handleErrorFormValidation(err, ErrChartValidateFields, w)
 		app.handleErrorFormValidation(err, ErrChartValidateFields, w)
-		return
+		return nil, err
 	}
 	}
 
 
 	// create a new agent
 	// create a new agent
@@ -293,15 +268,8 @@ func (app *App) HandleRollbackChart(w http.ResponseWriter, r *http.Request) {
 	if app.testing {
 	if app.testing {
 		agent = app.TestAgents.HelmAgent
 		agent = app.TestAgents.HelmAgent
 	} else {
 	} else {
-		agent, err = helm.GetAgentOutOfClusterConfig(form.ChartForm.Form, app.logger)
+		agent, err = helm.GetAgentOutOfClusterConfig(form.Form, app.logger)
 	}
 	}
 
 
-	err = agent.RollbackRelease(form.Name, form.Revision)
-
-	if err != nil {
-		app.handleErrorInternal(err, w)
-		return
-	}
-
-	w.WriteHeader(http.StatusOK)
+	return agent, err
 }
 }

+ 1 - 1
server/router/router.go

@@ -28,7 +28,7 @@ func New(a *api.App, store sessions.Store, cookieName string) *chi.Mux {
 		r.Method("POST", "/logout", auth.BasicAuthenticate(requestlog.NewHandler(a.HandleLogoutUser, l)))
 		r.Method("POST", "/logout", auth.BasicAuthenticate(requestlog.NewHandler(a.HandleLogoutUser, l)))
 
 
 		// /api/charts routes
 		// /api/charts routes
-		r.Method("GET", "/charts", auth.BasicAuthenticate(requestlog.NewHandler(a.HandleListCharts, l)))
+		r.Method("GET", "/charts", auth.BasicAuthenticate(requestlog.NewHandler(a.HandleListReleases, l)))
 		r.Method("GET", "/charts/{name}/history", auth.BasicAuthenticate(requestlog.NewHandler(a.HandleListChartHistory, l)))
 		r.Method("GET", "/charts/{name}/history", auth.BasicAuthenticate(requestlog.NewHandler(a.HandleListChartHistory, l)))
 		r.Method("POST", "/charts/{name}/upgrade", auth.BasicAuthenticate(requestlog.NewHandler(a.HandleUpgradeChart, l)))
 		r.Method("POST", "/charts/{name}/upgrade", auth.BasicAuthenticate(requestlog.NewHandler(a.HandleUpgradeChart, l)))
 		r.Method("GET", "/charts/{name}/{revision}", auth.BasicAuthenticate(requestlog.NewHandler(a.HandleGetChart, l)))
 		r.Method("GET", "/charts/{name}/{revision}", auth.BasicAuthenticate(requestlog.NewHandler(a.HandleGetChart, l)))