Alexander Belanger 4 лет назад
Родитель
Сommit
57140e50f9

+ 165 - 112
api/server/handlers/infra/delete.go

@@ -13,6 +13,10 @@ import (
 	"github.com/porter-dev/porter/internal/analytics"
 	"github.com/porter-dev/porter/internal/kubernetes/provisioner"
 	"github.com/porter-dev/porter/internal/kubernetes/provisioner/aws/ecr"
+	"github.com/porter-dev/porter/internal/kubernetes/provisioner/aws/eks"
+	"github.com/porter-dev/porter/internal/kubernetes/provisioner/do/docr"
+	"github.com/porter-dev/porter/internal/kubernetes/provisioner/do/doks"
+	"github.com/porter-dev/porter/internal/kubernetes/provisioner/gcp/gke"
 	"github.com/porter-dev/porter/internal/models"
 )
 
@@ -60,14 +64,14 @@ func (c *InfraDeleteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	switch infra.Kind {
 	case types.InfraECR:
 		err = destroyECR(c.Config(), infra)
-		// case types.InfraEKS:
-		// 	err = destroyEKS(c.Repo(), c.Config(), infra, request.Name)
-		// case types.InfraDOCR:
-		// 	err = destroyDOCR(c.Repo(), c.Config(), infra, request.Name)
-		// case types.InfraDOKS:
-		// 	err = destroyDOKS(c.Repo(), c.Config(), infra, request.Name)
-		// case types.InfraGKE:
-		// 	err = destroyGKE(c.Repo(), c.Config(), infra, request.Name)
+	case types.InfraEKS:
+		err = destroyEKS(c.Config(), infra)
+	case types.InfraDOCR:
+		err = destroyDOCR(c.Config(), infra)
+	case types.InfraDOKS:
+		err = destroyDOKS(c.Config(), infra)
+	case types.InfraGKE:
+		err = destroyGKE(c.Config(), infra)
 	}
 
 	if err != nil {
@@ -113,107 +117,156 @@ func destroyECR(conf *config.Config, infra *models.Infra) error {
 	return err
 }
 
-// func destroyEKS(repo repository.Repository, conf *config.Config, infra *models.Infra, name string) error {
-// 	awsInt, err := repo.AWSIntegration().ReadAWSIntegration(infra.ProjectID, infra.AWSIntegrationID)
-
-// 	if err != nil {
-// 		return err
-// 	}
-
-// 	_, err = conf.ProvisionerAgent.ProvisionEKS(
-// 		&kubernetes.SharedProvisionOpts{
-// 			ProjectID:           infra.ProjectID,
-// 			Repo:                repo,
-// 			Infra:               infra,
-// 			Operation:           provisioner.Destroy,
-// 			PGConf:              conf.DBConf,
-// 			RedisConf:           conf.RedisConf,
-// 			ProvImageTag:        conf.ServerConf.ProvisionerImageTag,
-// 			ProvImagePullSecret: conf.ServerConf.ProvisionerImagePullSecret,
-// 		},
-// 		awsInt,
-// 		name,
-// 		"",
-// 	)
-
-// 	return err
-// }
-
-// func destroyDOCR(repo repository.Repository, conf *config.Config, infra *models.Infra, name string) error {
-// 	doInt, err := repo.OAuthIntegration().ReadOAuthIntegration(infra.ProjectID, infra.DOIntegrationID)
-
-// 	if err != nil {
-// 		return err
-// 	}
-
-// 	_, err = conf.ProvisionerAgent.ProvisionDOCR(
-// 		&kubernetes.SharedProvisionOpts{
-// 			ProjectID:           infra.ProjectID,
-// 			Repo:                repo,
-// 			Infra:               infra,
-// 			Operation:           provisioner.Destroy,
-// 			PGConf:              conf.DBConf,
-// 			RedisConf:           conf.RedisConf,
-// 			ProvImageTag:        conf.ServerConf.ProvisionerImageTag,
-// 			ProvImagePullSecret: conf.ServerConf.ProvisionerImagePullSecret,
-// 		},
-// 		doInt,
-// 		conf.DOConf,
-// 		name,
-// 		"",
-// 	)
-
-// 	return err
-// }
-
-// func destroyDOKS(repo repository.Repository, conf *config.Config, infra *models.Infra, name string) error {
-// 	doInt, err := repo.OAuthIntegration().ReadOAuthIntegration(infra.ProjectID, infra.DOIntegrationID)
-
-// 	if err != nil {
-// 		return err
-// 	}
-
-// 	_, err = conf.ProvisionerAgent.ProvisionDOKS(
-// 		&kubernetes.SharedProvisionOpts{
-// 			ProjectID:           infra.ProjectID,
-// 			Repo:                repo,
-// 			Infra:               infra,
-// 			Operation:           provisioner.Destroy,
-// 			PGConf:              conf.DBConf,
-// 			RedisConf:           conf.RedisConf,
-// 			ProvImageTag:        conf.ServerConf.ProvisionerImageTag,
-// 			ProvImagePullSecret: conf.ServerConf.ProvisionerImagePullSecret,
-// 		},
-// 		doInt,
-// 		conf.DOConf,
-// 		"",
-// 		name,
-// 	)
-
-// 	return err
-// }
-
-// func destroyGKE(repo repository.Repository, conf *config.Config, infra *models.Infra, name string) error {
-// 	gcpInt, err := repo.GCPIntegration().ReadGCPIntegration(infra.ProjectID, infra.GCPIntegrationID)
-
-// 	if err != nil {
-// 		return err
-// 	}
-
-// 	_, err = conf.ProvisionerAgent.ProvisionGKE(
-// 		&kubernetes.SharedProvisionOpts{
-// 			ProjectID:           infra.ProjectID,
-// 			Repo:                repo,
-// 			Infra:               infra,
-// 			Operation:           provisioner.Destroy,
-// 			PGConf:              conf.DBConf,
-// 			RedisConf:           conf.RedisConf,
-// 			ProvImageTag:        conf.ServerConf.ProvisionerImageTag,
-// 			ProvImagePullSecret: conf.ServerConf.ProvisionerImagePullSecret,
-// 		},
-// 		gcpInt,
-// 		name,
-// 	)
-
-// 	return err
-// }
+func destroyEKS(conf *config.Config, infra *models.Infra) error {
+	lastAppliedEKS := &types.CreateEKSInfraRequest{}
+
+	// parse infra last applied into EKS config
+	if err := json.Unmarshal(infra.LastApplied, lastAppliedEKS); err != nil {
+		return err
+	}
+
+	awsInt, err := conf.Repo.AWSIntegration().ReadAWSIntegration(infra.ProjectID, infra.AWSIntegrationID)
+
+	if err != nil {
+		return err
+	}
+
+	opts, err := provision.GetSharedProvisionerOpts(conf, infra)
+
+	vaultToken := ""
+
+	if conf.CredentialBackend != nil {
+		vaultToken, err = conf.CredentialBackend.CreateAWSToken(awsInt)
+
+		if err != nil {
+			return err
+		}
+	}
+
+	opts.CredentialExchange.VaultToken = vaultToken
+	opts.EKS = &eks.Conf{
+		ClusterName: lastAppliedEKS.EKSName,
+		MachineType: lastAppliedEKS.MachineType,
+	}
+	opts.OperationKind = provisioner.Destroy
+
+	err = conf.ProvisionerAgent.Provision(opts)
+
+	return err
+}
+
+func destroyDOCR(conf *config.Config, infra *models.Infra) error {
+	lastAppliedDOCR := &types.CreateDOCRInfraRequest{}
+
+	// parse infra last applied into DOCR config
+	if err := json.Unmarshal(infra.LastApplied, lastAppliedDOCR); err != nil {
+		return err
+	}
+
+	doInt, err := conf.Repo.OAuthIntegration().ReadOAuthIntegration(infra.ProjectID, infra.DOIntegrationID)
+
+	if err != nil {
+		return err
+	}
+
+	opts, err := provision.GetSharedProvisionerOpts(conf, infra)
+
+	vaultToken := ""
+
+	if conf.CredentialBackend != nil {
+		vaultToken, err = conf.CredentialBackend.CreateOAuthToken(doInt)
+
+		if err != nil {
+			return err
+		}
+	}
+
+	opts.CredentialExchange.VaultToken = vaultToken
+	opts.DOCR = &docr.Conf{
+		DOCRName:             lastAppliedDOCR.DOCRName,
+		DOCRSubscriptionTier: lastAppliedDOCR.DOCRSubscriptionTier,
+	}
+
+	opts.OperationKind = provisioner.Destroy
+
+	err = conf.ProvisionerAgent.Provision(opts)
+
+	return err
+}
+
+func destroyDOKS(conf *config.Config, infra *models.Infra) error {
+	lastAppliedDOKS := &types.CreateDOKSInfraRequest{}
+
+	// parse infra last applied into DOKS config
+	if err := json.Unmarshal(infra.LastApplied, lastAppliedDOKS); err != nil {
+		return err
+	}
+
+	doInt, err := conf.Repo.OAuthIntegration().ReadOAuthIntegration(infra.ProjectID, infra.DOIntegrationID)
+
+	if err != nil {
+		return err
+	}
+
+	opts, err := provision.GetSharedProvisionerOpts(conf, infra)
+
+	vaultToken := ""
+
+	if conf.CredentialBackend != nil {
+		vaultToken, err = conf.CredentialBackend.CreateOAuthToken(doInt)
+
+		if err != nil {
+			return err
+		}
+	}
+
+	opts.CredentialExchange.VaultToken = vaultToken
+	opts.DOKS = &doks.Conf{
+		DORegion:        lastAppliedDOKS.DORegion,
+		DOKSClusterName: lastAppliedDOKS.DOKSName,
+	}
+
+	opts.OperationKind = provisioner.Destroy
+
+	err = conf.ProvisionerAgent.Provision(opts)
+
+	return err
+}
+
+func destroyGKE(conf *config.Config, infra *models.Infra) error {
+	lastAppliedGKE := &types.CreateGKEInfraRequest{}
+
+	// parse infra last applied into DOKS config
+	if err := json.Unmarshal(infra.LastApplied, lastAppliedGKE); err != nil {
+		return err
+	}
+
+	gcpInt, err := conf.Repo.GCPIntegration().ReadGCPIntegration(infra.ProjectID, infra.GCPIntegrationID)
+
+	if err != nil {
+		return err
+	}
+
+	opts, err := provision.GetSharedProvisionerOpts(conf, infra)
+
+	vaultToken := ""
+
+	if conf.CredentialBackend != nil {
+		vaultToken, err = conf.CredentialBackend.CreateGCPToken(gcpInt)
+
+		if err != nil {
+			return err
+		}
+	}
+
+	opts.CredentialExchange.VaultToken = vaultToken
+	opts.GKE = &gke.Conf{
+		ClusterName: lastAppliedGKE.GKEName,
+	}
+
+	opts.OperationKind = provisioner.Destroy
+
+	err = conf.ProvisionerAgent.Provision(opts)
+
+	return err
+}

+ 111 - 83
api/server/handlers/provision/provision_docr.go

@@ -1,11 +1,20 @@
 package provision
 
 import (
+	"encoding/json"
 	"net/http"
 
 	"github.com/porter-dev/porter/api/server/handlers"
 	"github.com/porter-dev/porter/api/server/shared"
+	"github.com/porter-dev/porter/api/server/shared/apierrors"
 	"github.com/porter-dev/porter/api/server/shared/config"
+	"github.com/porter-dev/porter/api/types"
+	"github.com/porter-dev/porter/internal/analytics"
+	"github.com/porter-dev/porter/internal/kubernetes/provisioner"
+	"github.com/porter-dev/porter/internal/kubernetes/provisioner/do/docr"
+	"github.com/porter-dev/porter/internal/models"
+	"github.com/porter-dev/porter/internal/repository"
+	"gorm.io/gorm"
 )
 
 type ProvisionDOCRHandler struct {
@@ -23,87 +32,106 @@ func NewProvisionDOCRHandler(
 }
 
 func (c *ProvisionDOCRHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	// // read the user and project from context
-	// user, _ := r.Context().Value(types.UserScope).(*models.User)
-	// proj, _ := r.Context().Value(types.ProjectScope).(*models.Project)
-
-	// request := &types.CreateDOCRInfraRequest{
-	// 	ProjectID: proj.ID,
-	// }
-
-	// if ok := c.DecodeAndValidate(w, r, request); !ok {
-	// 	return
-	// }
-
-	// // get the AWS integration
-	// doInt, err := c.Repo().OAuthIntegration().ReadOAuthIntegration(proj.ID, request.DOIntegrationID)
-
-	// if err != nil {
-	// 	if err == gorm.ErrRecordNotFound {
-	// 		c.HandleAPIError(w, r, apierrors.NewErrForbidden(err))
-	// 	} else {
-	// 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	}
-
-	// 	return
-	// }
-
-	// suffix, err := repository.GenerateRandomBytes(6)
-
-	// if err != nil {
-	// 	c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	return
-	// }
-
-	// infra := &models.Infra{
-	// 	Kind:            types.InfraDOCR,
-	// 	ProjectID:       proj.ID,
-	// 	Suffix:          suffix,
-	// 	Status:          types.StatusCreating,
-	// 	DOIntegrationID: request.DOIntegrationID,
-	// 	CreatedByUserID: user.ID,
-	// }
-
-	// // handle write to the database
-	// infra, err = c.Repo().Infra().CreateInfra(infra)
-
-	// if err != nil {
-	// 	c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	return
-	// }
-
-	// // launch provisioning pod
-	// _, err = c.Config().ProvisionerAgent.ProvisionDOCR(
-	// 	&kubernetes.SharedProvisionOpts{
-	// 		ProjectID:           proj.ID,
-	// 		Repo:                c.Repo(),
-	// 		Infra:               infra,
-	// 		Operation:           provisioner.Apply,
-	// 		PGConf:              c.Config().DBConf,
-	// 		RedisConf:           c.Config().RedisConf,
-	// 		ProvImageTag:        c.Config().ServerConf.ProvisionerImageTag,
-	// 		ProvImagePullSecret: c.Config().ServerConf.ProvisionerImagePullSecret,
-	// 	},
-	// 	doInt,
-	// 	c.Config().DOConf,
-	// 	request.DOCRName,
-	// 	request.DOCRSubscriptionTier,
-	// )
-
-	// if err != nil {
-	// 	infra.Status = types.StatusError
-	// 	infra, _ = c.Repo().Infra().UpdateInfra(infra)
-	// 	c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	return
-	// }
-
-	// c.Config().AnalyticsClient.Track(analytics.RegistryProvisioningStartTrack(
-	// 	&analytics.RegistryProvisioningStartTrackOpts{
-	// 		ProjectScopedTrackOpts: analytics.GetProjectScopedTrackOpts(user.ID, proj.ID),
-	// 		RegistryType:           types.InfraDOCR,
-	// 		InfraID:                infra.ID,
-	// 	},
-	// ))
-
-	// c.WriteResult(w, r, infra.ToInfraType())
+	// read the user and project from context
+	user, _ := r.Context().Value(types.UserScope).(*models.User)
+	proj, _ := r.Context().Value(types.ProjectScope).(*models.Project)
+
+	request := &types.CreateDOCRInfraRequest{
+		ProjectID: proj.ID,
+	}
+
+	if ok := c.DecodeAndValidate(w, r, request); !ok {
+		return
+	}
+
+	// get the DO integration, to check that integration exists and belongs to the project
+	doInt, err := c.Repo().OAuthIntegration().ReadOAuthIntegration(proj.ID, request.DOIntegrationID)
+
+	if err != nil {
+		if err == gorm.ErrRecordNotFound {
+			c.HandleAPIError(w, r, apierrors.NewErrForbidden(err))
+		} else {
+			c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		}
+
+		return
+	}
+
+	suffix, err := repository.GenerateRandomBytes(6)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	lastApplied, err := json.Marshal(request)
+
+	// parse infra last applied into DOCR config
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	infra := &models.Infra{
+		Kind:            types.InfraDOCR,
+		ProjectID:       proj.ID,
+		Suffix:          suffix,
+		Status:          types.StatusCreating,
+		DOIntegrationID: request.DOIntegrationID,
+		CreatedByUserID: user.ID,
+		LastApplied:     lastApplied,
+	}
+
+	// handle write to the database
+	infra, err = c.Repo().Infra().CreateInfra(infra)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	opts, err := GetSharedProvisionerOpts(c.Config(), infra)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	vaultToken := ""
+
+	if c.Config().CredentialBackend != nil {
+		vaultToken, err = c.Config().CredentialBackend.CreateOAuthToken(doInt)
+
+		if err != nil {
+			c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+			return
+		}
+	}
+
+	opts.CredentialExchange.VaultToken = vaultToken
+	opts.DOCR = &docr.Conf{
+		DOCRName:             request.DOCRName,
+		DOCRSubscriptionTier: request.DOCRSubscriptionTier,
+	}
+
+	opts.OperationKind = provisioner.Apply
+
+	err = c.Config().ProvisionerAgent.Provision(opts)
+
+	if err != nil {
+		infra.Status = types.StatusError
+		infra, _ = c.Repo().Infra().UpdateInfra(infra)
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	c.Config().AnalyticsClient.Track(analytics.RegistryProvisioningStartTrack(
+		&analytics.RegistryProvisioningStartTrackOpts{
+			ProjectScopedTrackOpts: analytics.GetProjectScopedTrackOpts(user.ID, proj.ID),
+			RegistryType:           types.InfraDOCR,
+			InfraID:                infra.ID,
+		},
+	))
+
+	c.WriteResult(w, r, infra.ToInfraType())
 }

+ 111 - 83
api/server/handlers/provision/provision_doks.go

@@ -1,11 +1,20 @@
 package provision
 
 import (
+	"encoding/json"
 	"net/http"
 
 	"github.com/porter-dev/porter/api/server/handlers"
 	"github.com/porter-dev/porter/api/server/shared"
+	"github.com/porter-dev/porter/api/server/shared/apierrors"
 	"github.com/porter-dev/porter/api/server/shared/config"
+	"github.com/porter-dev/porter/api/types"
+	"github.com/porter-dev/porter/internal/analytics"
+	"github.com/porter-dev/porter/internal/kubernetes/provisioner"
+	"github.com/porter-dev/porter/internal/kubernetes/provisioner/do/doks"
+	"github.com/porter-dev/porter/internal/models"
+	"github.com/porter-dev/porter/internal/repository"
+	"gorm.io/gorm"
 )
 
 type ProvisionDOKSHandler struct {
@@ -23,87 +32,106 @@ func NewProvisionDOKSHandler(
 }
 
 func (c *ProvisionDOKSHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	// // read the user and project from context
-	// user, _ := r.Context().Value(types.UserScope).(*models.User)
-	// proj, _ := r.Context().Value(types.ProjectScope).(*models.Project)
-
-	// request := &types.CreateDOKSInfraRequest{
-	// 	ProjectID: proj.ID,
-	// }
-
-	// if ok := c.DecodeAndValidate(w, r, request); !ok {
-	// 	return
-	// }
-
-	// // get the AWS integration
-	// doInt, err := c.Repo().OAuthIntegration().ReadOAuthIntegration(proj.ID, request.DOIntegrationID)
-
-	// if err != nil {
-	// 	if err == gorm.ErrRecordNotFound {
-	// 		c.HandleAPIError(w, r, apierrors.NewErrForbidden(err))
-	// 	} else {
-	// 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	}
-
-	// 	return
-	// }
-
-	// suffix, err := repository.GenerateRandomBytes(6)
-
-	// if err != nil {
-	// 	c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	return
-	// }
-
-	// infra := &models.Infra{
-	// 	Kind:            types.InfraDOKS,
-	// 	ProjectID:       proj.ID,
-	// 	Suffix:          suffix,
-	// 	Status:          types.StatusCreating,
-	// 	DOIntegrationID: request.DOIntegrationID,
-	// 	CreatedByUserID: user.ID,
-	// }
-
-	// // handle write to the database
-	// infra, err = c.Repo().Infra().CreateInfra(infra)
-
-	// if err != nil {
-	// 	c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	return
-	// }
-
-	// // launch provisioning pod
-	// _, err = c.Config().ProvisionerAgent.ProvisionDOKS(
-	// 	&kubernetes.SharedProvisionOpts{
-	// 		ProjectID:           proj.ID,
-	// 		Repo:                c.Repo(),
-	// 		Infra:               infra,
-	// 		Operation:           provisioner.Apply,
-	// 		PGConf:              c.Config().DBConf,
-	// 		RedisConf:           c.Config().RedisConf,
-	// 		ProvImageTag:        c.Config().ServerConf.ProvisionerImageTag,
-	// 		ProvImagePullSecret: c.Config().ServerConf.ProvisionerImagePullSecret,
-	// 	},
-	// 	doInt,
-	// 	c.Config().DOConf,
-	// 	request.DORegion,
-	// 	request.DOKSName,
-	// )
-
-	// if err != nil {
-	// 	infra.Status = types.StatusError
-	// 	infra, _ = c.Repo().Infra().UpdateInfra(infra)
-	// 	c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	return
-	// }
-
-	// c.Config().AnalyticsClient.Track(analytics.ClusterProvisioningStartTrack(
-	// 	&analytics.ClusterProvisioningStartTrackOpts{
-	// 		ProjectScopedTrackOpts: analytics.GetProjectScopedTrackOpts(user.ID, proj.ID),
-	// 		ClusterType:            types.InfraDOKS,
-	// 		InfraID:                infra.ID,
-	// 	},
-	// ))
-
-	// c.WriteResult(w, r, infra.ToInfraType())
+	// read the user and project from context
+	user, _ := r.Context().Value(types.UserScope).(*models.User)
+	proj, _ := r.Context().Value(types.ProjectScope).(*models.Project)
+
+	request := &types.CreateDOKSInfraRequest{
+		ProjectID: proj.ID,
+	}
+
+	if ok := c.DecodeAndValidate(w, r, request); !ok {
+		return
+	}
+
+	// get the DO integration, to check that integration exists and belongs to the project
+	doInt, err := c.Repo().OAuthIntegration().ReadOAuthIntegration(proj.ID, request.DOIntegrationID)
+
+	if err != nil {
+		if err == gorm.ErrRecordNotFound {
+			c.HandleAPIError(w, r, apierrors.NewErrForbidden(err))
+		} else {
+			c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		}
+
+		return
+	}
+
+	suffix, err := repository.GenerateRandomBytes(6)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	lastApplied, err := json.Marshal(request)
+
+	// parse infra last applied into DOKS config
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	infra := &models.Infra{
+		Kind:            types.InfraDOKS,
+		ProjectID:       proj.ID,
+		Suffix:          suffix,
+		Status:          types.StatusCreating,
+		DOIntegrationID: request.DOIntegrationID,
+		CreatedByUserID: user.ID,
+		LastApplied:     lastApplied,
+	}
+
+	// handle write to the database
+	infra, err = c.Repo().Infra().CreateInfra(infra)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	opts, err := GetSharedProvisionerOpts(c.Config(), infra)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	vaultToken := ""
+
+	if c.Config().CredentialBackend != nil {
+		vaultToken, err = c.Config().CredentialBackend.CreateOAuthToken(doInt)
+
+		if err != nil {
+			c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+			return
+		}
+	}
+
+	opts.CredentialExchange.VaultToken = vaultToken
+	opts.DOKS = &doks.Conf{
+		DORegion:        request.DORegion,
+		DOKSClusterName: request.DOKSName,
+	}
+
+	opts.OperationKind = provisioner.Apply
+
+	err = c.Config().ProvisionerAgent.Provision(opts)
+
+	if err != nil {
+		infra.Status = types.StatusError
+		infra, _ = c.Repo().Infra().UpdateInfra(infra)
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	c.Config().AnalyticsClient.Track(analytics.ClusterProvisioningStartTrack(
+		&analytics.ClusterProvisioningStartTrackOpts{
+			ProjectScopedTrackOpts: analytics.GetProjectScopedTrackOpts(user.ID, proj.ID),
+			ClusterType:            types.InfraDOKS,
+			InfraID:                infra.ID,
+		},
+	))
+
+	c.WriteResult(w, r, infra.ToInfraType())
 }

+ 110 - 82
api/server/handlers/provision/provision_eks.go

@@ -1,11 +1,20 @@
 package provision
 
 import (
+	"encoding/json"
 	"net/http"
 
 	"github.com/porter-dev/porter/api/server/handlers"
 	"github.com/porter-dev/porter/api/server/shared"
+	"github.com/porter-dev/porter/api/server/shared/apierrors"
 	"github.com/porter-dev/porter/api/server/shared/config"
+	"github.com/porter-dev/porter/api/types"
+	"github.com/porter-dev/porter/internal/analytics"
+	"github.com/porter-dev/porter/internal/kubernetes/provisioner"
+	"github.com/porter-dev/porter/internal/kubernetes/provisioner/aws/eks"
+	"github.com/porter-dev/porter/internal/models"
+	"github.com/porter-dev/porter/internal/repository"
+	"gorm.io/gorm"
 )
 
 type ProvisionEKSHandler struct {
@@ -23,86 +32,105 @@ func NewProvisionEKSHandler(
 }
 
 func (c *ProvisionEKSHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	// // read the user and project from context
-	// user, _ := r.Context().Value(types.UserScope).(*models.User)
-	// proj, _ := r.Context().Value(types.ProjectScope).(*models.Project)
-
-	// request := &types.CreateEKSInfraRequest{
-	// 	ProjectID: proj.ID,
-	// }
-
-	// if ok := c.DecodeAndValidate(w, r, request); !ok {
-	// 	return
-	// }
-
-	// // get the AWS integration
-	// awsInt, err := c.Repo().AWSIntegration().ReadAWSIntegration(proj.ID, request.AWSIntegrationID)
-
-	// if err != nil {
-	// 	if err == gorm.ErrRecordNotFound {
-	// 		c.HandleAPIError(w, r, apierrors.NewErrForbidden(err))
-	// 	} else {
-	// 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	}
-
-	// 	return
-	// }
-
-	// suffix, err := repository.GenerateRandomBytes(6)
-
-	// if err != nil {
-	// 	c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	return
-	// }
-
-	// infra := &models.Infra{
-	// 	Kind:             types.InfraEKS,
-	// 	ProjectID:        proj.ID,
-	// 	Suffix:           suffix,
-	// 	Status:           types.StatusCreating,
-	// 	AWSIntegrationID: request.AWSIntegrationID,
-	// 	CreatedByUserID:  user.ID,
-	// }
-
-	// // handle write to the database
-	// infra, err = c.Repo().Infra().CreateInfra(infra)
-
-	// if err != nil {
-	// 	c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	return
-	// }
-
-	// // launch provisioning pod
-	// _, err = c.Config().ProvisionerAgent.ProvisionEKS(
-	// 	&kubernetes.SharedProvisionOpts{
-	// 		ProjectID:           proj.ID,
-	// 		Repo:                c.Repo(),
-	// 		Infra:               infra,
-	// 		Operation:           provisioner.Apply,
-	// 		PGConf:              c.Config().DBConf,
-	// 		RedisConf:           c.Config().RedisConf,
-	// 		ProvImageTag:        c.Config().ServerConf.ProvisionerImageTag,
-	// 		ProvImagePullSecret: c.Config().ServerConf.ProvisionerImagePullSecret,
-	// 	},
-	// 	awsInt,
-	// 	request.EKSName,
-	// 	request.MachineType,
-	// )
-
-	// if err != nil {
-	// 	infra.Status = types.StatusError
-	// 	infra, _ = c.Repo().Infra().UpdateInfra(infra)
-	// 	c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	return
-	// }
-
-	// c.Config().AnalyticsClient.Track(analytics.ClusterProvisioningStartTrack(
-	// 	&analytics.ClusterProvisioningStartTrackOpts{
-	// 		ProjectScopedTrackOpts: analytics.GetProjectScopedTrackOpts(user.ID, proj.ID),
-	// 		ClusterType:            types.InfraEKS,
-	// 		InfraID:                infra.ID,
-	// 	},
-	// ))
-
-	// c.WriteResult(w, r, infra.ToInfraType())
+	// read the user and project from context
+	user, _ := r.Context().Value(types.UserScope).(*models.User)
+	proj, _ := r.Context().Value(types.ProjectScope).(*models.Project)
+
+	request := &types.CreateEKSInfraRequest{
+		ProjectID: proj.ID,
+	}
+
+	if ok := c.DecodeAndValidate(w, r, request); !ok {
+		return
+	}
+
+	// get the AWS integration, to check that integration exists and belongs to the project
+	awsInt, err := c.Repo().AWSIntegration().ReadAWSIntegration(proj.ID, request.AWSIntegrationID)
+
+	if err != nil {
+		if err == gorm.ErrRecordNotFound {
+			c.HandleAPIError(w, r, apierrors.NewErrForbidden(err))
+		} else {
+			c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		}
+
+		return
+	}
+
+	suffix, err := repository.GenerateRandomBytes(6)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	lastApplied, err := json.Marshal(request)
+
+	// parse infra last applied into EKS config
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	infra := &models.Infra{
+		Kind:             types.InfraEKS,
+		ProjectID:        proj.ID,
+		Suffix:           suffix,
+		Status:           types.StatusCreating,
+		AWSIntegrationID: request.AWSIntegrationID,
+		CreatedByUserID:  user.ID,
+		LastApplied:      lastApplied,
+	}
+
+	// handle write to the database
+	infra, err = c.Repo().Infra().CreateInfra(infra)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	opts, err := GetSharedProvisionerOpts(c.Config(), infra)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	vaultToken := ""
+
+	if c.Config().CredentialBackend != nil {
+		vaultToken, err = c.Config().CredentialBackend.CreateAWSToken(awsInt)
+
+		if err != nil {
+			c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+			return
+		}
+	}
+
+	opts.CredentialExchange.VaultToken = vaultToken
+	opts.EKS = &eks.Conf{
+		ClusterName: request.EKSName,
+		MachineType: request.MachineType,
+	}
+	opts.OperationKind = provisioner.Apply
+
+	err = c.Config().ProvisionerAgent.Provision(opts)
+
+	if err != nil {
+		infra.Status = types.StatusError
+		infra, _ = c.Repo().Infra().UpdateInfra(infra)
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	c.Config().AnalyticsClient.Track(analytics.ClusterProvisioningStartTrack(
+		&analytics.ClusterProvisioningStartTrackOpts{
+			ProjectScopedTrackOpts: analytics.GetProjectScopedTrackOpts(user.ID, proj.ID),
+			ClusterType:            types.InfraEKS,
+			InfraID:                infra.ID,
+		},
+	))
+
+	c.WriteResult(w, r, infra.ToInfraType())
 }

+ 105 - 80
api/server/handlers/provision/provision_gcr.go

@@ -1,11 +1,19 @@
 package provision
 
 import (
+	"encoding/json"
 	"net/http"
 
 	"github.com/porter-dev/porter/api/server/handlers"
 	"github.com/porter-dev/porter/api/server/shared"
+	"github.com/porter-dev/porter/api/server/shared/apierrors"
 	"github.com/porter-dev/porter/api/server/shared/config"
+	"github.com/porter-dev/porter/api/types"
+	"github.com/porter-dev/porter/internal/analytics"
+	"github.com/porter-dev/porter/internal/kubernetes/provisioner"
+	"github.com/porter-dev/porter/internal/models"
+	"github.com/porter-dev/porter/internal/repository"
+	"gorm.io/gorm"
 )
 
 type ProvisionGCRHandler struct {
@@ -23,84 +31,101 @@ func NewProvisionGCRHandler(
 }
 
 func (c *ProvisionGCRHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	// // read the user and project from context
-	// user, _ := r.Context().Value(types.UserScope).(*models.User)
-	// proj, _ := r.Context().Value(types.ProjectScope).(*models.Project)
-
-	// request := &types.CreateGCRInfraRequest{
-	// 	ProjectID: proj.ID,
-	// }
-
-	// if ok := c.DecodeAndValidate(w, r, request); !ok {
-	// 	return
-	// }
-
-	// // get the AWS integration
-	// gcpInt, err := c.Repo().GCPIntegration().ReadGCPIntegration(proj.ID, request.GCPIntegrationID)
-
-	// if err != nil {
-	// 	if err == gorm.ErrRecordNotFound {
-	// 		c.HandleAPIError(w, r, apierrors.NewErrForbidden(err))
-	// 	} else {
-	// 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	}
-
-	// 	return
-	// }
-
-	// suffix, err := repository.GenerateRandomBytes(6)
-
-	// if err != nil {
-	// 	c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	return
-	// }
-
-	// infra := &models.Infra{
-	// 	Kind:             types.InfraGCR,
-	// 	ProjectID:        proj.ID,
-	// 	Suffix:           suffix,
-	// 	Status:           types.StatusCreating,
-	// 	GCPIntegrationID: request.GCPIntegrationID,
-	// 	CreatedByUserID:  user.ID,
-	// }
-
-	// // handle write to the database
-	// infra, err = c.Repo().Infra().CreateInfra(infra)
-
-	// if err != nil {
-	// 	c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	return
-	// }
-
-	// // launch provisioning pod
-	// _, err = c.Config().ProvisionerAgent.ProvisionGCR(
-	// 	&kubernetes.SharedProvisionOpts{
-	// 		ProjectID:           proj.ID,
-	// 		Repo:                c.Repo(),
-	// 		Infra:               infra,
-	// 		Operation:           provisioner.Apply,
-	// 		PGConf:              c.Config().DBConf,
-	// 		RedisConf:           c.Config().RedisConf,
-	// 		ProvImageTag:        c.Config().ServerConf.ProvisionerImageTag,
-	// 		ProvImagePullSecret: c.Config().ServerConf.ProvisionerImagePullSecret,
-	// 	},
-	// 	gcpInt,
-	// )
-
-	// if err != nil {
-	// 	infra.Status = types.StatusError
-	// 	infra, _ = c.Repo().Infra().UpdateInfra(infra)
-	// 	c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	return
-	// }
-
-	// c.Config().AnalyticsClient.Track(analytics.RegistryProvisioningStartTrack(
-	// 	&analytics.RegistryProvisioningStartTrackOpts{
-	// 		ProjectScopedTrackOpts: analytics.GetProjectScopedTrackOpts(user.ID, proj.ID),
-	// 		RegistryType:           types.InfraGCR,
-	// 		InfraID:                infra.ID,
-	// 	},
-	// ))
-
-	// c.WriteResult(w, r, infra.ToInfraType())
+	// read the user and project from context
+	user, _ := r.Context().Value(types.UserScope).(*models.User)
+	proj, _ := r.Context().Value(types.ProjectScope).(*models.Project)
+
+	request := &types.CreateGCRInfraRequest{
+		ProjectID: proj.ID,
+	}
+
+	if ok := c.DecodeAndValidate(w, r, request); !ok {
+		return
+	}
+
+	// get the GCP integration, to check that integration exists and belongs to the project
+	gcpInt, err := c.Repo().GCPIntegration().ReadGCPIntegration(proj.ID, request.GCPIntegrationID)
+
+	if err != nil {
+		if err == gorm.ErrRecordNotFound {
+			c.HandleAPIError(w, r, apierrors.NewErrForbidden(err))
+		} else {
+			c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		}
+
+		return
+	}
+
+	suffix, err := repository.GenerateRandomBytes(6)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	lastApplied, err := json.Marshal(request)
+
+	// parse infra last applied into GCR config
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	infra := &models.Infra{
+		Kind:             types.InfraGCR,
+		ProjectID:        proj.ID,
+		Suffix:           suffix,
+		Status:           types.StatusCreating,
+		GCPIntegrationID: request.GCPIntegrationID,
+		CreatedByUserID:  user.ID,
+		LastApplied:      lastApplied,
+	}
+
+	// handle write to the database
+	infra, err = c.Repo().Infra().CreateInfra(infra)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	opts, err := GetSharedProvisionerOpts(c.Config(), infra)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	vaultToken := ""
+
+	if c.Config().CredentialBackend != nil {
+		vaultToken, err = c.Config().CredentialBackend.CreateGCPToken(gcpInt)
+
+		if err != nil {
+			c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+			return
+		}
+	}
+
+	opts.CredentialExchange.VaultToken = vaultToken
+	opts.OperationKind = provisioner.Apply
+
+	err = c.Config().ProvisionerAgent.Provision(opts)
+
+	if err != nil {
+		infra.Status = types.StatusError
+		infra, _ = c.Repo().Infra().UpdateInfra(infra)
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	c.Config().AnalyticsClient.Track(analytics.RegistryProvisioningStartTrack(
+		&analytics.RegistryProvisioningStartTrackOpts{
+			ProjectScopedTrackOpts: analytics.GetProjectScopedTrackOpts(user.ID, proj.ID),
+			RegistryType:           types.InfraGCR,
+			InfraID:                infra.ID,
+		},
+	))
+
+	c.WriteResult(w, r, infra.ToInfraType())
 }

+ 110 - 81
api/server/handlers/provision/provision_gke.go

@@ -1,11 +1,20 @@
 package provision
 
 import (
+	"encoding/json"
 	"net/http"
 
 	"github.com/porter-dev/porter/api/server/handlers"
 	"github.com/porter-dev/porter/api/server/shared"
+	"github.com/porter-dev/porter/api/server/shared/apierrors"
 	"github.com/porter-dev/porter/api/server/shared/config"
+	"github.com/porter-dev/porter/api/types"
+	"github.com/porter-dev/porter/internal/analytics"
+	"github.com/porter-dev/porter/internal/kubernetes/provisioner"
+	"github.com/porter-dev/porter/internal/kubernetes/provisioner/gcp/gke"
+	"github.com/porter-dev/porter/internal/models"
+	"github.com/porter-dev/porter/internal/repository"
+	"gorm.io/gorm"
 )
 
 type ProvisionGKEHandler struct {
@@ -23,85 +32,105 @@ func NewProvisionGKEHandler(
 }
 
 func (c *ProvisionGKEHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	// // read the user and project from context
-	// user, _ := r.Context().Value(types.UserScope).(*models.User)
-	// proj, _ := r.Context().Value(types.ProjectScope).(*models.Project)
-
-	// request := &types.CreateGKEInfraRequest{
-	// 	ProjectID: proj.ID,
-	// }
-
-	// if ok := c.DecodeAndValidate(w, r, request); !ok {
-	// 	return
-	// }
-
-	// // get the AWS integration
-	// gcpInt, err := c.Repo().GCPIntegration().ReadGCPIntegration(proj.ID, request.GCPIntegrationID)
-
-	// if err != nil {
-	// 	if err == gorm.ErrRecordNotFound {
-	// 		c.HandleAPIError(w, r, apierrors.NewErrForbidden(err))
-	// 	} else {
-	// 		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	}
-
-	// 	return
-	// }
-
-	// suffix, err := repository.GenerateRandomBytes(6)
-
-	// if err != nil {
-	// 	c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	return
-	// }
-
-	// infra := &models.Infra{
-	// 	Kind:             types.InfraGKE,
-	// 	ProjectID:        proj.ID,
-	// 	Suffix:           suffix,
-	// 	Status:           types.StatusCreating,
-	// 	GCPIntegrationID: request.GCPIntegrationID,
-	// 	CreatedByUserID:  user.ID,
-	// }
-
-	// // handle write to the database
-	// infra, err = c.Repo().Infra().CreateInfra(infra)
-
-	// if err != nil {
-	// 	c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	return
-	// }
-
-	// // launch provisioning pod
-	// _, err = c.Config().ProvisionerAgent.ProvisionGKE(
-	// 	&kubernetes.SharedProvisionOpts{
-	// 		ProjectID:           proj.ID,
-	// 		Repo:                c.Repo(),
-	// 		Infra:               infra,
-	// 		Operation:           provisioner.Apply,
-	// 		PGConf:              c.Config().DBConf,
-	// 		RedisConf:           c.Config().RedisConf,
-	// 		ProvImageTag:        c.Config().ServerConf.ProvisionerImageTag,
-	// 		ProvImagePullSecret: c.Config().ServerConf.ProvisionerImagePullSecret,
-	// 	},
-	// 	gcpInt,
-	// 	request.GKEName,
-	// )
-
-	// if err != nil {
-	// 	infra.Status = types.StatusError
-	// 	infra, _ = c.Repo().Infra().UpdateInfra(infra)
-	// 	c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
-	// 	return
-	// }
-
-	// c.Config().AnalyticsClient.Track(analytics.ClusterProvisioningStartTrack(
-	// 	&analytics.ClusterProvisioningStartTrackOpts{
-	// 		ProjectScopedTrackOpts: analytics.GetProjectScopedTrackOpts(user.ID, proj.ID),
-	// 		ClusterType:            types.InfraGKE,
-	// 		InfraID:                infra.ID,
-	// 	},
-	// ))
-
-	// c.WriteResult(w, r, infra.ToInfraType())
+	// read the user and project from context
+	user, _ := r.Context().Value(types.UserScope).(*models.User)
+	proj, _ := r.Context().Value(types.ProjectScope).(*models.Project)
+
+	request := &types.CreateGKEInfraRequest{
+		ProjectID: proj.ID,
+	}
+
+	if ok := c.DecodeAndValidate(w, r, request); !ok {
+		return
+	}
+
+	// get the GCP integration, to check that integration exists and belongs to the project
+	gcpInt, err := c.Repo().GCPIntegration().ReadGCPIntegration(proj.ID, request.GCPIntegrationID)
+
+	if err != nil {
+		if err == gorm.ErrRecordNotFound {
+			c.HandleAPIError(w, r, apierrors.NewErrForbidden(err))
+		} else {
+			c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		}
+
+		return
+	}
+
+	suffix, err := repository.GenerateRandomBytes(6)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	lastApplied, err := json.Marshal(request)
+
+	// parse infra last applied into GKE config
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	infra := &models.Infra{
+		Kind:             types.InfraGKE,
+		ProjectID:        proj.ID,
+		Suffix:           suffix,
+		Status:           types.StatusCreating,
+		GCPIntegrationID: request.GCPIntegrationID,
+		CreatedByUserID:  user.ID,
+		LastApplied:      lastApplied,
+	}
+
+	// handle write to the database
+	infra, err = c.Repo().Infra().CreateInfra(infra)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	opts, err := GetSharedProvisionerOpts(c.Config(), infra)
+
+	if err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	vaultToken := ""
+
+	if c.Config().CredentialBackend != nil {
+		vaultToken, err = c.Config().CredentialBackend.CreateGCPToken(gcpInt)
+
+		if err != nil {
+			c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+			return
+		}
+	}
+
+	opts.CredentialExchange.VaultToken = vaultToken
+	opts.GKE = &gke.Conf{
+		ClusterName: request.GKEName,
+	}
+
+	opts.OperationKind = provisioner.Apply
+
+	err = c.Config().ProvisionerAgent.Provision(opts)
+
+	if err != nil {
+		infra.Status = types.StatusError
+		infra, _ = c.Repo().Infra().UpdateInfra(infra)
+		c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		return
+	}
+
+	c.Config().AnalyticsClient.Track(analytics.ClusterProvisioningStartTrack(
+		&analytics.ClusterProvisioningStartTrackOpts{
+			ProjectScopedTrackOpts: analytics.GetProjectScopedTrackOpts(user.ID, proj.ID),
+			ClusterType:            types.InfraGKE,
+			InfraID:                infra.ID,
+		},
+	))
+
+	c.WriteResult(w, r, infra.ToInfraType())
 }