chart_handler.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. package api
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "net/url"
  6. "strconv"
  7. "github.com/go-chi/chi"
  8. "github.com/porter-dev/porter/internal/forms"
  9. "github.com/porter-dev/porter/internal/helm"
  10. )
  11. // Enumeration of chart API error codes, represented as int64
  12. const (
  13. ErrChartDecode ErrorCode = iota + 600
  14. ErrChartValidateFields
  15. )
  16. // HandleListCharts retrieves a list of charts with various filter options
  17. func (app *App) HandleListCharts(w http.ResponseWriter, r *http.Request) {
  18. session, err := app.store.Get(r, app.cookieName)
  19. if err != nil {
  20. app.handleErrorFormDecoding(err, ErrChartDecode, w)
  21. return
  22. }
  23. vals, err := url.ParseQuery(r.URL.RawQuery)
  24. if err != nil {
  25. app.handleErrorFormDecoding(err, ErrChartDecode, w)
  26. return
  27. }
  28. // get the filter options
  29. form := &forms.ListChartForm{
  30. ChartForm: &forms.ChartForm{
  31. Form: &helm.Form{},
  32. },
  33. ListFilter: &helm.ListFilter{},
  34. }
  35. form.PopulateListFromQueryParams(vals)
  36. if sessID, ok := session.Values["user_id"].(uint); ok {
  37. form.PopulateHelmOptionsFromUserID(sessID, app.repo.User)
  38. }
  39. // validate the form
  40. if err := app.validator.Struct(form); err != nil {
  41. app.handleErrorFormValidation(err, ErrChartValidateFields, w)
  42. return
  43. }
  44. // create a new agent
  45. var agent *helm.Agent
  46. if app.testing {
  47. agent = app.TestAgents.HelmAgent
  48. } else {
  49. agent, err = helm.GetAgentOutOfClusterConfig(form.ChartForm.Form, app.logger)
  50. }
  51. releases, err := agent.ListReleases(form.Namespace, form.ListFilter)
  52. if err != nil {
  53. app.handleErrorFormValidation(err, ErrChartValidateFields, w)
  54. return
  55. }
  56. if err := json.NewEncoder(w).Encode(releases); err != nil {
  57. app.handleErrorFormDecoding(err, ErrChartDecode, w)
  58. return
  59. }
  60. }
  61. // HandleGetChart retrieves a single chart based on a name and revision
  62. func (app *App) HandleGetChart(w http.ResponseWriter, r *http.Request) {
  63. session, err := app.store.Get(r, app.cookieName)
  64. if err != nil {
  65. app.handleErrorFormDecoding(err, ErrChartDecode, w)
  66. return
  67. }
  68. name := chi.URLParam(r, "name")
  69. revision, err := strconv.ParseUint(chi.URLParam(r, "revision"), 0, 64)
  70. // get the filter options
  71. form := &forms.GetChartForm{
  72. ChartForm: &forms.ChartForm{
  73. Form: &helm.Form{},
  74. },
  75. Name: name,
  76. Revision: int(revision),
  77. }
  78. vals, err := url.ParseQuery(r.URL.RawQuery)
  79. if err != nil {
  80. app.handleErrorFormDecoding(err, ErrChartDecode, w)
  81. return
  82. }
  83. form.PopulateHelmOptionsFromQueryParams(vals)
  84. if sessID, ok := session.Values["user_id"].(uint); ok {
  85. form.PopulateHelmOptionsFromUserID(sessID, app.repo.User)
  86. }
  87. // validate the form
  88. if err := app.validator.Struct(form); err != nil {
  89. app.handleErrorFormValidation(err, ErrChartValidateFields, w)
  90. return
  91. }
  92. // create a new agent
  93. var agent *helm.Agent
  94. if app.testing {
  95. agent = app.TestAgents.HelmAgent
  96. } else {
  97. agent, err = helm.GetAgentOutOfClusterConfig(form.ChartForm.Form, app.logger)
  98. }
  99. release, err := agent.GetRelease(form.Name, form.Revision)
  100. if err != nil {
  101. app.handleErrorFormValidation(err, ErrChartValidateFields, w)
  102. return
  103. }
  104. if err := json.NewEncoder(w).Encode(release); err != nil {
  105. app.handleErrorFormDecoding(err, ErrChartDecode, w)
  106. return
  107. }
  108. }
  109. // HandleListChartHistory retrieves a history of charts based on a chart name
  110. func (app *App) HandleListChartHistory(w http.ResponseWriter, r *http.Request) {
  111. session, err := app.store.Get(r, app.cookieName)
  112. if err != nil {
  113. app.handleErrorFormDecoding(err, ErrChartDecode, w)
  114. return
  115. }
  116. name := chi.URLParam(r, "name")
  117. // get the filter options
  118. form := &forms.ListChartHistoryForm{
  119. ChartForm: &forms.ChartForm{
  120. Form: &helm.Form{},
  121. },
  122. Name: name,
  123. }
  124. vals, err := url.ParseQuery(r.URL.RawQuery)
  125. if err != nil {
  126. app.handleErrorFormDecoding(err, ErrChartDecode, w)
  127. return
  128. }
  129. form.PopulateHelmOptionsFromQueryParams(vals)
  130. if sessID, ok := session.Values["user_id"].(uint); ok {
  131. form.PopulateHelmOptionsFromUserID(sessID, app.repo.User)
  132. }
  133. // validate the form
  134. if err := app.validator.Struct(form); err != nil {
  135. app.handleErrorFormValidation(err, ErrChartValidateFields, w)
  136. return
  137. }
  138. // create a new agent
  139. var agent *helm.Agent
  140. if app.testing {
  141. agent = app.TestAgents.HelmAgent
  142. } else {
  143. agent, err = helm.GetAgentOutOfClusterConfig(form.ChartForm.Form, app.logger)
  144. }
  145. release, err := agent.GetReleaseHistory(form.Name)
  146. if err != nil {
  147. app.handleErrorFormValidation(err, ErrChartValidateFields, w)
  148. return
  149. }
  150. if err := json.NewEncoder(w).Encode(release); err != nil {
  151. app.handleErrorFormDecoding(err, ErrChartDecode, w)
  152. return
  153. }
  154. }
  155. // HandleUpgradeChart upgrades a chart with new values.yaml
  156. func (app *App) HandleUpgradeChart(w http.ResponseWriter, r *http.Request) {
  157. session, err := app.store.Get(r, app.cookieName)
  158. if err != nil {
  159. app.handleErrorFormDecoding(err, ErrChartDecode, w)
  160. return
  161. }
  162. name := chi.URLParam(r, "name")
  163. // get the filter options
  164. form := &forms.UpgradeChartForm{
  165. ChartForm: &forms.ChartForm{
  166. Form: &helm.Form{},
  167. },
  168. Name: name,
  169. }
  170. // decode from JSON to form value
  171. if err := json.NewDecoder(r.Body).Decode(form); err != nil {
  172. app.handleErrorFormDecoding(err, ErrUserDecode, w)
  173. return
  174. }
  175. if sessID, ok := session.Values["user_id"].(uint); ok {
  176. form.PopulateHelmOptionsFromUserID(sessID, app.repo.User)
  177. }
  178. // validate the form
  179. if err := app.validator.Struct(form); err != nil {
  180. app.handleErrorFormValidation(err, ErrChartValidateFields, w)
  181. return
  182. }
  183. // create a new agent
  184. var agent *helm.Agent
  185. if app.testing {
  186. agent = app.TestAgents.HelmAgent
  187. } else {
  188. agent, err = helm.GetAgentOutOfClusterConfig(form.ChartForm.Form, app.logger)
  189. }
  190. rel, err := agent.UpgradeChart(form.Name, form.Values)
  191. if err != nil {
  192. app.handleErrorInternal(err, w)
  193. return
  194. }
  195. w.WriteHeader(http.StatusOK)
  196. if err := json.NewEncoder(w).Encode(rel); err != nil {
  197. app.handleErrorFormDecoding(err, ErrChartDecode, w)
  198. return
  199. }
  200. }
  201. // HandleRollbackChart rolls a release back to a specified revision
  202. func (app *App) HandleRollbackChart(w http.ResponseWriter, r *http.Request) {
  203. session, err := app.store.Get(r, app.cookieName)
  204. if err != nil {
  205. app.handleErrorFormDecoding(err, ErrChartDecode, w)
  206. return
  207. }
  208. name := chi.URLParam(r, "name")
  209. revision, err := strconv.ParseUint(chi.URLParam(r, "revision"), 0, 64)
  210. // get the filter options
  211. form := &forms.GetChartForm{
  212. ChartForm: &forms.ChartForm{
  213. Form: &helm.Form{},
  214. },
  215. Name: name,
  216. Revision: int(revision),
  217. }
  218. // decode from JSON to form value
  219. if err := json.NewDecoder(r.Body).Decode(form); err != nil {
  220. app.handleErrorFormDecoding(err, ErrUserDecode, w)
  221. return
  222. }
  223. if sessID, ok := session.Values["user_id"].(uint); ok {
  224. form.PopulateHelmOptionsFromUserID(sessID, app.repo.User)
  225. }
  226. // validate the form
  227. if err := app.validator.Struct(form); err != nil {
  228. app.handleErrorFormValidation(err, ErrChartValidateFields, w)
  229. return
  230. }
  231. // create a new agent
  232. var agent *helm.Agent
  233. if app.testing {
  234. agent = app.TestAgents.HelmAgent
  235. } else {
  236. agent, err = helm.GetAgentOutOfClusterConfig(form.ChartForm.Form, app.logger)
  237. }
  238. err = agent.RollbackRelease(form.Name, form.Revision)
  239. if err != nil {
  240. app.handleErrorInternal(err, w)
  241. return
  242. }
  243. w.WriteHeader(http.StatusOK)
  244. }