delete.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. package infra
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "github.com/porter-dev/porter/api/server/handlers"
  6. "github.com/porter-dev/porter/api/server/handlers/provision"
  7. "github.com/porter-dev/porter/api/server/shared"
  8. "github.com/porter-dev/porter/api/server/shared/apierrors"
  9. "github.com/porter-dev/porter/api/server/shared/config"
  10. "github.com/porter-dev/porter/api/types"
  11. "github.com/porter-dev/porter/internal/analytics"
  12. "github.com/porter-dev/porter/internal/kubernetes/provisioner"
  13. "github.com/porter-dev/porter/internal/kubernetes/provisioner/aws/ecr"
  14. "github.com/porter-dev/porter/internal/kubernetes/provisioner/aws/eks"
  15. "github.com/porter-dev/porter/internal/kubernetes/provisioner/do/docr"
  16. "github.com/porter-dev/porter/internal/kubernetes/provisioner/do/doks"
  17. "github.com/porter-dev/porter/internal/kubernetes/provisioner/gcp/gke"
  18. "github.com/porter-dev/porter/internal/models"
  19. )
  20. type InfraDeleteHandler struct {
  21. handlers.PorterHandlerReadWriter
  22. }
  23. func NewInfraDeleteHandler(
  24. config *config.Config,
  25. decoderValidator shared.RequestDecoderValidator,
  26. writer shared.ResultWriter,
  27. ) *InfraDeleteHandler {
  28. return &InfraDeleteHandler{
  29. PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
  30. }
  31. }
  32. func (c *InfraDeleteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  33. infra, _ := r.Context().Value(types.InfraScope).(*models.Infra)
  34. request := &types.DeleteInfraRequest{}
  35. if ok := c.DecodeAndValidate(w, r, request); !ok {
  36. return
  37. }
  38. if infra.Kind == types.InfraDOKS || infra.Kind == types.InfraGKE || infra.Kind == types.InfraEKS {
  39. c.Config().AnalyticsClient.Track(analytics.ClusterDestroyingStartTrack(
  40. &analytics.ClusterDestroyingStartTrackOpts{
  41. ClusterScopedTrackOpts: analytics.GetClusterScopedTrackOpts(infra.CreatedByUserID, infra.ProjectID, 0),
  42. ClusterType: infra.Kind,
  43. InfraID: infra.ID,
  44. },
  45. ))
  46. }
  47. infra.Status = types.StatusDestroying
  48. infra, err := c.Repo().Infra().UpdateInfra(infra)
  49. if err != nil {
  50. c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
  51. return
  52. }
  53. switch infra.Kind {
  54. case types.InfraECR:
  55. err = destroyECR(c.Config(), infra)
  56. case types.InfraEKS:
  57. err = destroyEKS(c.Config(), infra)
  58. case types.InfraDOCR:
  59. err = destroyDOCR(c.Config(), infra)
  60. case types.InfraDOKS:
  61. err = destroyDOKS(c.Config(), infra)
  62. case types.InfraGKE:
  63. err = destroyGKE(c.Config(), infra)
  64. }
  65. if err != nil {
  66. c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
  67. return
  68. }
  69. }
  70. func destroyECR(conf *config.Config, infra *models.Infra) error {
  71. lastAppliedECR := &types.CreateECRInfraRequest{}
  72. // parse infra last applied into ECR config
  73. if err := json.Unmarshal(infra.LastApplied, lastAppliedECR); err != nil {
  74. return err
  75. }
  76. awsInt, err := conf.Repo.AWSIntegration().ReadAWSIntegration(infra.ProjectID, infra.AWSIntegrationID)
  77. if err != nil {
  78. return err
  79. }
  80. opts, err := provision.GetSharedProvisionerOpts(conf, infra)
  81. vaultToken := ""
  82. if conf.CredentialBackend != nil {
  83. vaultToken, err = conf.CredentialBackend.CreateAWSToken(awsInt)
  84. if err != nil {
  85. return err
  86. }
  87. }
  88. opts.CredentialExchange.VaultToken = vaultToken
  89. opts.ECR = &ecr.Conf{
  90. AWSRegion: awsInt.AWSRegion,
  91. ECRName: lastAppliedECR.ECRName,
  92. }
  93. opts.OperationKind = provisioner.Destroy
  94. err = conf.ProvisionerAgent.Provision(opts)
  95. return err
  96. }
  97. func destroyEKS(conf *config.Config, infra *models.Infra) error {
  98. lastAppliedEKS := &types.CreateEKSInfraRequest{}
  99. // parse infra last applied into EKS config
  100. if err := json.Unmarshal(infra.LastApplied, lastAppliedEKS); err != nil {
  101. return err
  102. }
  103. awsInt, err := conf.Repo.AWSIntegration().ReadAWSIntegration(infra.ProjectID, infra.AWSIntegrationID)
  104. if err != nil {
  105. return err
  106. }
  107. opts, err := provision.GetSharedProvisionerOpts(conf, infra)
  108. vaultToken := ""
  109. if conf.CredentialBackend != nil {
  110. vaultToken, err = conf.CredentialBackend.CreateAWSToken(awsInt)
  111. if err != nil {
  112. return err
  113. }
  114. }
  115. opts.CredentialExchange.VaultToken = vaultToken
  116. opts.EKS = &eks.Conf{
  117. AWSRegion: awsInt.AWSRegion,
  118. ClusterName: lastAppliedEKS.EKSName,
  119. MachineType: lastAppliedEKS.MachineType,
  120. IssuerEmail: lastAppliedEKS.IssuerEmail,
  121. }
  122. opts.OperationKind = provisioner.Destroy
  123. err = conf.ProvisionerAgent.Provision(opts)
  124. return err
  125. }
  126. func destroyDOCR(conf *config.Config, infra *models.Infra) error {
  127. lastAppliedDOCR := &types.CreateDOCRInfraRequest{}
  128. // parse infra last applied into DOCR config
  129. if err := json.Unmarshal(infra.LastApplied, lastAppliedDOCR); err != nil {
  130. return err
  131. }
  132. doInt, err := conf.Repo.OAuthIntegration().ReadOAuthIntegration(infra.ProjectID, infra.DOIntegrationID)
  133. if err != nil {
  134. return err
  135. }
  136. opts, err := provision.GetSharedProvisionerOpts(conf, infra)
  137. vaultToken := ""
  138. if conf.CredentialBackend != nil {
  139. vaultToken, err = conf.CredentialBackend.CreateOAuthToken(doInt)
  140. if err != nil {
  141. return err
  142. }
  143. }
  144. opts.CredentialExchange.VaultToken = vaultToken
  145. opts.DOCR = &docr.Conf{
  146. DOCRName: lastAppliedDOCR.DOCRName,
  147. DOCRSubscriptionTier: lastAppliedDOCR.DOCRSubscriptionTier,
  148. }
  149. opts.OperationKind = provisioner.Destroy
  150. err = conf.ProvisionerAgent.Provision(opts)
  151. return err
  152. }
  153. func destroyDOKS(conf *config.Config, infra *models.Infra) error {
  154. lastAppliedDOKS := &types.CreateDOKSInfraRequest{}
  155. // parse infra last applied into DOKS config
  156. if err := json.Unmarshal(infra.LastApplied, lastAppliedDOKS); err != nil {
  157. return err
  158. }
  159. doInt, err := conf.Repo.OAuthIntegration().ReadOAuthIntegration(infra.ProjectID, infra.DOIntegrationID)
  160. if err != nil {
  161. return err
  162. }
  163. opts, err := provision.GetSharedProvisionerOpts(conf, infra)
  164. vaultToken := ""
  165. if conf.CredentialBackend != nil {
  166. vaultToken, err = conf.CredentialBackend.CreateOAuthToken(doInt)
  167. if err != nil {
  168. return err
  169. }
  170. }
  171. opts.CredentialExchange.VaultToken = vaultToken
  172. opts.DOKS = &doks.Conf{
  173. DORegion: lastAppliedDOKS.DORegion,
  174. DOKSClusterName: lastAppliedDOKS.DOKSName,
  175. IssuerEmail: lastAppliedDOKS.IssuerEmail,
  176. }
  177. opts.OperationKind = provisioner.Destroy
  178. err = conf.ProvisionerAgent.Provision(opts)
  179. return err
  180. }
  181. func destroyGKE(conf *config.Config, infra *models.Infra) error {
  182. lastAppliedGKE := &types.CreateGKEInfraRequest{}
  183. // parse infra last applied into DOKS config
  184. if err := json.Unmarshal(infra.LastApplied, lastAppliedGKE); err != nil {
  185. return err
  186. }
  187. gcpInt, err := conf.Repo.GCPIntegration().ReadGCPIntegration(infra.ProjectID, infra.GCPIntegrationID)
  188. if err != nil {
  189. return err
  190. }
  191. opts, err := provision.GetSharedProvisionerOpts(conf, infra)
  192. vaultToken := ""
  193. if conf.CredentialBackend != nil {
  194. vaultToken, err = conf.CredentialBackend.CreateGCPToken(gcpInt)
  195. if err != nil {
  196. return err
  197. }
  198. }
  199. opts.CredentialExchange.VaultToken = vaultToken
  200. opts.GKE = &gke.Conf{
  201. GCPProjectID: gcpInt.GCPProjectID,
  202. GCPRegion: lastAppliedGKE.GCPRegion,
  203. ClusterName: lastAppliedGKE.GKEName,
  204. IssuerEmail: lastAppliedGKE.IssuerEmail,
  205. }
  206. opts.OperationKind = provisioner.Destroy
  207. err = conf.ProvisionerAgent.Provision(opts)
  208. return err
  209. }