provision_handler.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. package api
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "strconv"
  6. "github.com/go-chi/chi"
  7. "github.com/porter-dev/porter/internal/forms"
  8. "github.com/porter-dev/porter/internal/kubernetes"
  9. "github.com/porter-dev/porter/internal/kubernetes/provisioner"
  10. "github.com/porter-dev/porter/internal/adapter"
  11. )
  12. // HandleProvisionTest will create a test resource by deploying a provisioner
  13. // container pod
  14. func (app *App) HandleProvisionTest(w http.ResponseWriter, r *http.Request) {
  15. projID, err := strconv.ParseUint(chi.URLParam(r, "project_id"), 0, 64)
  16. if err != nil || projID == 0 {
  17. app.handleErrorFormDecoding(err, ErrProjectDecode, w)
  18. return
  19. }
  20. // create a new agent
  21. agent, err := kubernetes.GetAgentInClusterConfig()
  22. if err != nil {
  23. app.handleErrorDataRead(err, w)
  24. return
  25. }
  26. _, err = agent.ProvisionTest(uint(projID))
  27. if err != nil {
  28. app.handleErrorInternal(err, w)
  29. return
  30. }
  31. w.WriteHeader(http.StatusOK)
  32. }
  33. // HandleProvisionAWSECRInfra provisions a new aws ECR instance for a project
  34. func (app *App) HandleProvisionAWSECRInfra(w http.ResponseWriter, r *http.Request) {
  35. projID, err := strconv.ParseUint(chi.URLParam(r, "project_id"), 0, 64)
  36. if err != nil || projID == 0 {
  37. app.handleErrorFormDecoding(err, ErrProjectDecode, w)
  38. return
  39. }
  40. form := &forms.CreateECRInfra{
  41. ProjectID: uint(projID),
  42. }
  43. // decode from JSON to form value
  44. if err := json.NewDecoder(r.Body).Decode(form); err != nil {
  45. app.handleErrorFormDecoding(err, ErrProjectDecode, w)
  46. return
  47. }
  48. // validate the form
  49. if err := app.validator.Struct(form); err != nil {
  50. app.handleErrorFormValidation(err, ErrProjectValidateFields, w)
  51. return
  52. }
  53. // convert the form to an aws infra instance
  54. infra, err := form.ToAWSInfra()
  55. if err != nil {
  56. app.handleErrorFormDecoding(err, ErrProjectDecode, w)
  57. return
  58. }
  59. // handle write to the database
  60. infra, err = app.Repo.AWSInfra.CreateAWSInfra(infra)
  61. if err != nil {
  62. app.handleErrorDataWrite(err, w)
  63. return
  64. }
  65. awsInt, err := app.Repo.AWSIntegration.ReadAWSIntegration(infra.AWSIntegrationID)
  66. if err != nil {
  67. app.handleErrorDataRead(err, w)
  68. return
  69. }
  70. // launch provisioning pod
  71. agent, err := kubernetes.GetAgentInClusterConfig()
  72. if err != nil {
  73. app.handleErrorDataRead(err, w)
  74. return
  75. }
  76. _, err = agent.ProvisionECR(
  77. uint(projID),
  78. awsInt,
  79. form.ECRName,
  80. infra,
  81. )
  82. if err != nil {
  83. app.handleErrorInternal(err, w)
  84. return
  85. }
  86. app.Logger.Info().Msgf("New aws ecr infra created: %d", infra.ID)
  87. w.WriteHeader(http.StatusCreated)
  88. infraExt := infra.Externalize()
  89. if err := json.NewEncoder(w).Encode(infraExt); err != nil {
  90. app.handleErrorFormDecoding(err, ErrProjectDecode, w)
  91. return
  92. }
  93. }
  94. // HandleProvisionAWSEKSInfra provisions a new aws EKS instance for a project
  95. func (app *App) HandleProvisionAWSEKSInfra(w http.ResponseWriter, r *http.Request) {
  96. projID, err := strconv.ParseUint(chi.URLParam(r, "project_id"), 0, 64)
  97. if err != nil || projID == 0 {
  98. app.handleErrorFormDecoding(err, ErrProjectDecode, w)
  99. return
  100. }
  101. form := &forms.CreateEKSInfra{
  102. ProjectID: uint(projID),
  103. }
  104. // decode from JSON to form value
  105. if err := json.NewDecoder(r.Body).Decode(form); err != nil {
  106. app.handleErrorFormDecoding(err, ErrProjectDecode, w)
  107. return
  108. }
  109. // validate the form
  110. if err := app.validator.Struct(form); err != nil {
  111. app.handleErrorFormValidation(err, ErrProjectValidateFields, w)
  112. return
  113. }
  114. // convert the form to an aws infra instance
  115. infra, err := form.ToAWSInfra()
  116. if err != nil {
  117. app.handleErrorFormDecoding(err, ErrProjectDecode, w)
  118. return
  119. }
  120. // handle write to the database
  121. infra, err = app.Repo.AWSInfra.CreateAWSInfra(infra)
  122. if err != nil {
  123. app.handleErrorDataWrite(err, w)
  124. return
  125. }
  126. awsInt, err := app.Repo.AWSIntegration.ReadAWSIntegration(infra.AWSIntegrationID)
  127. if err != nil {
  128. app.handleErrorDataRead(err, w)
  129. return
  130. }
  131. // launch provisioning pod
  132. agent, err := kubernetes.GetAgentInClusterConfig()
  133. if err != nil {
  134. app.handleErrorDataRead(err, w)
  135. return
  136. }
  137. _, err = agent.ProvisionEKS(
  138. uint(projID),
  139. awsInt,
  140. form.EKSName,
  141. infra,
  142. )
  143. if err != nil {
  144. app.handleErrorInternal(err, w)
  145. return
  146. }
  147. app.Logger.Info().Msgf("New aws eks infra created: %d", infra.ID)
  148. w.WriteHeader(http.StatusCreated)
  149. infraExt := infra.Externalize()
  150. if err := json.NewEncoder(w).Encode(infraExt); err != nil {
  151. app.handleErrorFormDecoding(err, ErrProjectDecode, w)
  152. return
  153. }
  154. }
  155. // HandleGetProvisioningLogs returns real-time logs of the provisioning process via websockets
  156. func (app *App) HandleGetProvisioningLogs(w http.ResponseWriter, r *http.Request) {
  157. // get path parameters
  158. infraID, err := strconv.ParseUint(chi.URLParam(r, "infra_id"), 10, 64)
  159. if err != nil {
  160. app.handleErrorFormDecoding(err, ErrProjectDecode, w)
  161. return
  162. }
  163. // read infra to get id
  164. infra, err := app.Repo.AWSInfra.ReadAWSInfra(uint(infraID))
  165. if err != nil {
  166. app.handleErrorDataRead(err, w)
  167. return
  168. }
  169. streamName := infra.GetID()
  170. upgrader.CheckOrigin = func(r *http.Request) bool { return true }
  171. // upgrade to websocket.
  172. conn, err := upgrader.Upgrade(w, r, nil)
  173. if err != nil {
  174. app.handleErrorUpgradeWebsocket(err, w)
  175. }
  176. client, err := adapter.NewRedisClient(app.RedisConf)
  177. if err != nil {
  178. app.handleErrorInternal(err, w)
  179. return
  180. }
  181. err = provisioner.ResourceStream(client, streamName, conn)
  182. if err != nil {
  183. app.handleErrorWebsocketWrite(err, w)
  184. return
  185. }
  186. }