Alexander Belanger 4 vuotta sitten
vanhempi
sitoutus
4aa920a982
3 muutettua tiedostoa jossa 328 lisäystä ja 126 poistoa
  1. 135 0
      api/server/handlers/provision/provision_ecr.go
  2. 105 0
      api/types/provision.go
  3. 88 126
      internal/kubernetes/agent.go

+ 135 - 0
api/server/handlers/provision/provision_ecr.go

@@ -0,0 +1,135 @@
+package provision
+
+import (
+	"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/config"
+)
+
+type ProvisionECRHandler struct {
+	handlers.PorterHandlerReadWriter
+}
+
+func NewProvisionECRHandler(
+	config *config.Config,
+	decoderValidator shared.RequestDecoderValidator,
+	writer shared.ResultWriter,
+) *ProvisionECRHandler {
+	return &ProvisionECRHandler{
+		PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
+	}
+}
+
+func (c *ProvisionECRHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	// read the project from context
+	// proj, _ := r.Context().Value(types.ProjectScope).(*models.Project)
+
+	// request := &types.CreateClusterManualRequest{}
+
+	// if ok := c.DecodeAndValidate(w, r, request); !ok {
+	// 	return
+	// }
+
+	// cluster, err := getClusterModelFromManualRequest(c.Repo(), proj, request)
+
+	// if err != nil {
+	// 	c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+	// 	return
+	// }
+
+	// cluster, err = c.Repo().Cluster().CreateCluster(cluster)
+
+	// if err != nil {
+	// 	c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+	// 	return
+	// }
+
+	// c.WriteResult(w, r, cluster.ToClusterType())
+}
+
+// HandleProvisionAWSECRInfra provisions a new aws ECR instance for a project
+// func (app *App) HandleProvisionAWSECRInfra(w http.ResponseWriter, r *http.Request) {
+// 	projID, err := strconv.ParseUint(chi.URLParam(r, "project_id"), 0, 64)
+
+// 	if err != nil || projID == 0 {
+// 		app.handleErrorFormDecoding(err, ErrProjectDecode, w)
+// 		return
+// 	}
+
+// 	form := &forms.CreateECRInfra{
+// 		ProjectID: uint(projID),
+// 	}
+
+// 	// decode from JSON to form value
+// 	if err := json.NewDecoder(r.Body).Decode(form); err != nil {
+// 		app.handleErrorFormDecoding(err, ErrProjectDecode, w)
+// 		return
+// 	}
+
+// 	// validate the form
+// 	if err := app.validator.Struct(form); err != nil {
+// 		app.handleErrorFormValidation(err, ErrProjectValidateFields, w)
+// 		return
+// 	}
+
+// 	// convert the form to an aws infra instance
+// 	infra, err := form.ToInfra()
+
+// 	if err != nil {
+// 		app.handleErrorFormDecoding(err, ErrProjectDecode, w)
+// 		return
+// 	}
+
+// 	// handle write to the database
+// 	infra, err = app.Repo.Infra().CreateInfra(infra)
+
+// 	if err != nil {
+// 		app.handleErrorDataWrite(err, w)
+// 		return
+// 	}
+
+// 	awsInt, err := app.Repo.AWSIntegration().ReadAWSIntegration(infra.AWSIntegrationID)
+
+// 	if err != nil {
+// 		infra.Status = types.StatusError
+// 		infra, _ = app.Repo.Infra().UpdateInfra(infra)
+
+// 		app.handleErrorDataRead(err, w)
+// 		return
+// 	}
+
+// 	// launch provisioning pod
+// 	_, err = app.ProvisionerAgent.ProvisionECR(
+// 		uint(projID),
+// 		awsInt,
+// 		form.ECRName,
+// 		app.Repo,
+// 		infra,
+// 		provisioner.Apply,
+// 		&app.DBConf,
+// 		app.RedisConf,
+// 		app.ServerConf.ProvisionerImageTag,
+// 		app.ServerConf.ProvisionerImagePullSecret,
+// 	)
+
+// 	if err != nil {
+// 		infra.Status = types.StatusError
+// 		infra, _ = app.Repo.Infra().UpdateInfra(infra)
+
+// 		app.handleErrorInternal(err, w)
+// 		return
+// 	}
+
+// 	app.Logger.Info().Msgf("New aws ecr infra created: %d", infra.ID)
+
+// 	w.WriteHeader(http.StatusCreated)
+
+// 	infraExt := infra.ToInfraType()
+
+// 	if err := json.NewEncoder(w).Encode(infraExt); err != nil {
+// 		app.handleErrorFormDecoding(err, ErrProjectDecode, w)
+// 		return
+// 	}
+// }

+ 105 - 0
api/types/provision.go

@@ -0,0 +1,105 @@
+package types
+
+type CreateECRInfraRequest struct {
+	ECRName          string `json:"ecr_name" form:"required"`
+	ProjectID        uint   `json:"project_id" form:"required"`
+	AWSIntegrationID uint   `json:"aws_integration_id" form:"required"`
+}
+
+// ToInfra converts the form to a gorm aws infra model
+// func (ce *CreateECRInfra) ToInfra() (*models.Infra, error) {
+// 	return &models.Infra{
+// 		Kind:             types.InfraECR,
+// 		ProjectID:        ce.ProjectID,
+// 		Suffix:           stringWithCharset(6, randCharset),
+// 		Status:           types.StatusCreating,
+// 		AWSIntegrationID: ce.AWSIntegrationID,
+// 	}, nil
+// }
+
+type CreateEKSInfraRequest struct {
+	EKSName          string `json:"eks_name" form:"required"`
+	MachineType      string `json:"machine_type"`
+	ProjectID        uint   `json:"project_id" form:"required"`
+	AWSIntegrationID uint   `json:"aws_integration_id" form:"required"`
+}
+
+// ToInfra converts the form to a gorm aws infra model
+// func (ce *CreateEKSInfra) ToInfra() (*models.Infra, error) {
+// 	return &models.Infra{
+// 		Kind:             types.InfraEKS,
+// 		ProjectID:        ce.ProjectID,
+// 		Suffix:           stringWithCharset(6, randCharset),
+// 		Status:           types.StatusCreating,
+// 		AWSIntegrationID: ce.AWSIntegrationID,
+// 	}, nil
+// }
+
+type CreateGCRInfraRequest struct {
+	ProjectID        uint `json:"project_id" form:"required"`
+	GCPIntegrationID uint `json:"gcp_integration_id" form:"required"`
+}
+
+// ToInfra converts the form to a gorm aws infra model
+// func (ce *CreateGCRInfra) ToInfra() (*models.Infra, error) {
+// 	return &models.Infra{
+// 		Kind:             types.InfraGCR,
+// 		ProjectID:        ce.ProjectID,
+// 		Suffix:           stringWithCharset(6, randCharset),
+// 		Status:           types.StatusCreating,
+// 		GCPIntegrationID: ce.GCPIntegrationID,
+// 	}, nil
+// }
+
+type CreateGKEInfraRequest struct {
+	GKEName          string `json:"gke_name" form:"required"`
+	ProjectID        uint   `json:"project_id" form:"required"`
+	GCPIntegrationID uint   `json:"gcp_integration_id" form:"required"`
+}
+
+// ToInfra converts the form to a gorm aws infra model
+// func (ce *CreateGKEInfra) ToInfra() (*models.Infra, error) {
+// 	return &models.Infra{
+// 		Kind:             types.InfraGKE,
+// 		ProjectID:        ce.ProjectID,
+// 		Suffix:           stringWithCharset(6, randCharset),
+// 		Status:           types.StatusCreating,
+// 		GCPIntegrationID: ce.GCPIntegrationID,
+// 	}, nil
+// }
+
+type CreateDOCRInfraRequest struct {
+	DOCRName             string `json:"docr_name" form:"required"`
+	DOCRSubscriptionTier string `json:"docr_subscription_tier" form:"required"`
+	ProjectID            uint   `json:"project_id" form:"required"`
+	DOIntegrationID      uint   `json:"do_integration_id" form:"required"`
+}
+
+// ToInfra converts the form to a gorm infra model
+// func (de *CreateDOCRInfra) ToInfra() (*models.Infra, error) {
+// 	return &models.Infra{
+// 		Kind:            types.InfraDOCR,
+// 		ProjectID:       de.ProjectID,
+// 		Suffix:          stringWithCharset(6, randCharset),
+// 		Status:          types.StatusCreating,
+// 		DOIntegrationID: de.DOIntegrationID,
+// 	}, nil
+// }
+
+type CreateDOKSInfraRequest struct {
+	DORegion        string `json:"do_region" form:"required"`
+	DOKSName        string `json:"doks_name" form:"required"`
+	ProjectID       uint   `json:"project_id" form:"required"`
+	DOIntegrationID uint   `json:"do_integration_id" form:"required"`
+}
+
+// ToInfra converts the form to a gorm infra model
+// func (de *CreateDOKSInfra) ToInfra() (*models.Infra, error) {
+// 	return &models.Infra{
+// 		Kind:            types.InfraDOKS,
+// 		ProjectID:       de.ProjectID,
+// 		Suffix:          stringWithCharset(6, randCharset),
+// 		Status:          types.StatusCreating,
+// 		DOIntegrationID: de.DOIntegrationID,
+// 	}, nil
+// }

+ 88 - 126
internal/kubernetes/agent.go

@@ -877,30 +877,34 @@ func (a *Agent) StreamHelmReleases(conn *websocket.Conn, chartList []string, sel
 	}
 }
 
+type SharedProvisionOpts struct {
+	ProjectID           uint
+	Repo                repository.Repository
+	Infra               *models.Infra
+	Operation           provisioner.ProvisionerOperation
+	PGConf              *env.DBConf
+	RedisConf           *env.RedisConf
+	ProvImageTag        string
+	ProvImagePullSecret string
+}
+
 // ProvisionECR spawns a new provisioning pod that creates an ECR instance
 func (a *Agent) ProvisionECR(
-	projectID uint,
+	opts *SharedProvisionOpts,
 	awsConf *integrations.AWSIntegration,
 	ecrName string,
-	repo repository.Repository,
-	infra *models.Infra,
-	operation provisioner.ProvisionerOperation,
-	pgConf *env.DBConf,
-	redisConf *env.RedisConf,
-	provImageTag string,
-	provImagePullSecret string,
 ) (*batchv1.Job, error) {
-	id := infra.GetUniqueName()
+	id := opts.Infra.GetUniqueName()
 	prov := &provisioner.Conf{
 		ID:                  id,
-		Name:                fmt.Sprintf("prov-%s-%s", id, string(operation)),
+		Name:                fmt.Sprintf("prov-%s-%s", id, string(opts.Operation)),
 		Kind:                provisioner.ECR,
-		Operation:           operation,
-		Redis:               redisConf,
-		Postgres:            pgConf,
-		ProvisionerImageTag: provImageTag,
-		ImagePullSecret:     provImagePullSecret,
-		LastApplied:         infra.LastApplied,
+		Operation:           opts.Operation,
+		Redis:               opts.RedisConf,
+		Postgres:            opts.PGConf,
+		ProvisionerImageTag: opts.ProvImageTag,
+		ImagePullSecret:     opts.ProvImagePullSecret,
+		LastApplied:         opts.Infra.LastApplied,
 		AWS: &aws.Conf{
 			AWSRegion:          awsConf.AWSRegion,
 			AWSAccessKeyID:     string(awsConf.AWSAccessKeyID),
@@ -911,33 +915,26 @@ func (a *Agent) ProvisionECR(
 		},
 	}
 
-	return a.provision(prov, infra, repo)
+	return a.provision(prov, opts.Infra, opts.Repo)
 }
 
 // ProvisionEKS spawns a new provisioning pod that creates an EKS instance
 func (a *Agent) ProvisionEKS(
-	projectID uint,
+	opts *SharedProvisionOpts,
 	awsConf *integrations.AWSIntegration,
 	eksName, machineType string,
-	repo repository.Repository,
-	infra *models.Infra,
-	operation provisioner.ProvisionerOperation,
-	pgConf *env.DBConf,
-	redisConf *env.RedisConf,
-	provImageTag string,
-	provImagePullSecret string,
 ) (*batchv1.Job, error) {
-	id := infra.GetUniqueName()
+	id := opts.Infra.GetUniqueName()
 	prov := &provisioner.Conf{
 		ID:                  id,
-		Name:                fmt.Sprintf("prov-%s-%s", id, string(operation)),
+		Name:                fmt.Sprintf("prov-%s-%s", id, string(opts.Operation)),
 		Kind:                provisioner.EKS,
-		Operation:           operation,
-		Redis:               redisConf,
-		Postgres:            pgConf,
-		ProvisionerImageTag: provImageTag,
-		ImagePullSecret:     provImagePullSecret,
-		LastApplied:         infra.LastApplied,
+		Operation:           opts.Operation,
+		Redis:               opts.RedisConf,
+		Postgres:            opts.PGConf,
+		ProvisionerImageTag: opts.ProvImageTag,
+		ImagePullSecret:     opts.ProvImagePullSecret,
+		LastApplied:         opts.Infra.LastApplied,
 		AWS: &aws.Conf{
 			AWSRegion:          awsConf.AWSRegion,
 			AWSAccessKeyID:     string(awsConf.AWSAccessKeyID),
@@ -949,32 +946,25 @@ func (a *Agent) ProvisionEKS(
 		},
 	}
 
-	return a.provision(prov, infra, repo)
+	return a.provision(prov, opts.Infra, opts.Repo)
 }
 
 // ProvisionGCR spawns a new provisioning pod that creates a GCR instance
 func (a *Agent) ProvisionGCR(
-	projectID uint,
+	opts *SharedProvisionOpts,
 	gcpConf *integrations.GCPIntegration,
-	repo repository.Repository,
-	infra *models.Infra,
-	operation provisioner.ProvisionerOperation,
-	pgConf *env.DBConf,
-	redisConf *env.RedisConf,
-	provImageTag string,
-	provImagePullSecret string,
 ) (*batchv1.Job, error) {
-	id := infra.GetUniqueName()
+	id := opts.Infra.GetUniqueName()
 	prov := &provisioner.Conf{
 		ID:                  id,
-		Name:                fmt.Sprintf("prov-%s-%s", id, string(operation)),
+		Name:                fmt.Sprintf("prov-%s-%s", id, string(opts.Operation)),
 		Kind:                provisioner.GCR,
-		Operation:           operation,
-		Redis:               redisConf,
-		Postgres:            pgConf,
-		ProvisionerImageTag: provImageTag,
-		ImagePullSecret:     provImagePullSecret,
-		LastApplied:         infra.LastApplied,
+		Operation:           opts.Operation,
+		Redis:               opts.RedisConf,
+		Postgres:            opts.PGConf,
+		ProvisionerImageTag: opts.ProvImageTag,
+		ImagePullSecret:     opts.ProvImagePullSecret,
+		LastApplied:         opts.Infra.LastApplied,
 		GCP: &gcp.Conf{
 			GCPRegion:    gcpConf.GCPRegion,
 			GCPProjectID: gcpConf.GCPProjectID,
@@ -982,33 +972,26 @@ func (a *Agent) ProvisionGCR(
 		},
 	}
 
-	return a.provision(prov, infra, repo)
+	return a.provision(prov, opts.Infra, opts.Repo)
 }
 
 // ProvisionGKE spawns a new provisioning pod that creates a GKE instance
 func (a *Agent) ProvisionGKE(
-	projectID uint,
+	opts *SharedProvisionOpts,
 	gcpConf *integrations.GCPIntegration,
 	gkeName string,
-	repo repository.Repository,
-	infra *models.Infra,
-	operation provisioner.ProvisionerOperation,
-	pgConf *env.DBConf,
-	redisConf *env.RedisConf,
-	provImageTag string,
-	provImagePullSecret string,
 ) (*batchv1.Job, error) {
-	id := infra.GetUniqueName()
+	id := opts.Infra.GetUniqueName()
 	prov := &provisioner.Conf{
 		ID:                  id,
-		Name:                fmt.Sprintf("prov-%s-%s", id, string(operation)),
+		Name:                fmt.Sprintf("prov-%s-%s", id, string(opts.Operation)),
 		Kind:                provisioner.GKE,
-		Operation:           operation,
-		Redis:               redisConf,
-		Postgres:            pgConf,
-		ProvisionerImageTag: provImageTag,
-		ImagePullSecret:     provImagePullSecret,
-		LastApplied:         infra.LastApplied,
+		Operation:           opts.Operation,
+		Redis:               opts.RedisConf,
+		Postgres:            opts.PGConf,
+		ProvisionerImageTag: opts.ProvImageTag,
+		ImagePullSecret:     opts.ProvImagePullSecret,
+		LastApplied:         opts.Infra.LastApplied,
 		GCP: &gcp.Conf{
 			GCPRegion:    gcpConf.GCPRegion,
 			GCPProjectID: gcpConf.GCPProjectID,
@@ -1019,50 +1002,43 @@ func (a *Agent) ProvisionGKE(
 		},
 	}
 
-	return a.provision(prov, infra, repo)
+	return a.provision(prov, opts.Infra, opts.Repo)
 }
 
 // ProvisionDOCR spawns a new provisioning pod that creates a DOCR instance
 func (a *Agent) ProvisionDOCR(
-	projectID uint,
+	opts *SharedProvisionOpts,
 	doConf *integrations.OAuthIntegration,
 	doAuth *oauth2.Config,
-	repo repository.Repository,
 	docrName, docrSubscriptionTier string,
-	infra *models.Infra,
-	operation provisioner.ProvisionerOperation,
-	pgConf *env.DBConf,
-	redisConf *env.RedisConf,
-	provImageTag string,
-	provImagePullSecret string,
 ) (*batchv1.Job, error) {
 	// get the token
-	oauthInt, err := repo.OAuthIntegration().ReadOAuthIntegration(
-		projectID,
-		infra.DOIntegrationID,
+	oauthInt, err := opts.Repo.OAuthIntegration().ReadOAuthIntegration(
+		opts.ProjectID,
+		opts.Infra.DOIntegrationID,
 	)
 
 	if err != nil {
 		return nil, err
 	}
 
-	tok, _, err := oauth.GetAccessToken(oauthInt.SharedOAuthModel, doAuth, oauth.MakeUpdateOAuthIntegrationTokenFunction(oauthInt, repo))
+	tok, _, err := oauth.GetAccessToken(oauthInt.SharedOAuthModel, doAuth, oauth.MakeUpdateOAuthIntegrationTokenFunction(oauthInt, opts.Repo))
 
 	if err != nil {
 		return nil, err
 	}
 
-	id := infra.GetUniqueName()
+	id := opts.Infra.GetUniqueName()
 	prov := &provisioner.Conf{
 		ID:                  id,
-		Name:                fmt.Sprintf("prov-%s-%s", id, string(operation)),
+		Name:                fmt.Sprintf("prov-%s-%s", id, string(opts.Operation)),
 		Kind:                provisioner.DOCR,
-		Operation:           operation,
-		Redis:               redisConf,
-		Postgres:            pgConf,
-		ProvisionerImageTag: provImageTag,
-		ImagePullSecret:     provImagePullSecret,
-		LastApplied:         infra.LastApplied,
+		Operation:           opts.Operation,
+		Redis:               opts.RedisConf,
+		Postgres:            opts.PGConf,
+		ProvisionerImageTag: opts.ProvImageTag,
+		ImagePullSecret:     opts.ProvImagePullSecret,
+		LastApplied:         opts.Infra.LastApplied,
 		DO: &do.Conf{
 			DOToken: tok,
 		},
@@ -1072,50 +1048,43 @@ func (a *Agent) ProvisionDOCR(
 		},
 	}
 
-	return a.provision(prov, infra, repo)
+	return a.provision(prov, opts.Infra, opts.Repo)
 }
 
 // ProvisionDOKS spawns a new provisioning pod that creates a DOKS instance
 func (a *Agent) ProvisionDOKS(
-	projectID uint,
+	opts *SharedProvisionOpts,
 	doConf *integrations.OAuthIntegration,
 	doAuth *oauth2.Config,
-	repo repository.Repository,
 	doRegion, doksClusterName string,
-	infra *models.Infra,
-	operation provisioner.ProvisionerOperation,
-	pgConf *env.DBConf,
-	redisConf *env.RedisConf,
-	provImageTag string,
-	provImagePullSecret string,
 ) (*batchv1.Job, error) {
 	// get the token
-	oauthInt, err := repo.OAuthIntegration().ReadOAuthIntegration(
-		projectID,
-		infra.DOIntegrationID,
+	oauthInt, err := opts.Repo.OAuthIntegration().ReadOAuthIntegration(
+		opts.ProjectID,
+		opts.Infra.DOIntegrationID,
 	)
 
 	if err != nil {
 		return nil, err
 	}
 
-	tok, _, err := oauth.GetAccessToken(oauthInt.SharedOAuthModel, doAuth, oauth.MakeUpdateOAuthIntegrationTokenFunction(oauthInt, repo))
+	tok, _, err := oauth.GetAccessToken(oauthInt.SharedOAuthModel, doAuth, oauth.MakeUpdateOAuthIntegrationTokenFunction(oauthInt, opts.Repo))
 
 	if err != nil {
 		return nil, err
 	}
 
-	id := infra.GetUniqueName()
+	id := opts.Infra.GetUniqueName()
 	prov := &provisioner.Conf{
 		ID:                  id,
-		Name:                fmt.Sprintf("prov-%s-%s", id, string(operation)),
+		Name:                fmt.Sprintf("prov-%s-%s", id, string(opts.Operation)),
 		Kind:                provisioner.DOKS,
-		Operation:           operation,
-		Redis:               redisConf,
-		Postgres:            pgConf,
-		LastApplied:         infra.LastApplied,
-		ProvisionerImageTag: provImageTag,
-		ImagePullSecret:     provImagePullSecret,
+		Operation:           opts.Operation,
+		Redis:               opts.RedisConf,
+		Postgres:            opts.PGConf,
+		LastApplied:         opts.Infra.LastApplied,
+		ProvisionerImageTag: opts.ProvImageTag,
+		ImagePullSecret:     opts.ProvImagePullSecret,
 		DO: &do.Conf{
 			DOToken: tok,
 		},
@@ -1125,34 +1094,27 @@ func (a *Agent) ProvisionDOKS(
 		},
 	}
 
-	return a.provision(prov, infra, repo)
+	return a.provision(prov, opts.Infra, opts.Repo)
 }
 
 // ProvisionTest spawns a new provisioning pod that tests provisioning
 func (a *Agent) ProvisionTest(
-	projectID uint,
-	infra *models.Infra,
-	repo repository.Repository,
-	operation provisioner.ProvisionerOperation,
-	pgConf *env.DBConf,
-	redisConf *env.RedisConf,
-	provImageTag string,
-	provImagePullSecret string,
+	opts *SharedProvisionOpts,
 ) (*batchv1.Job, error) {
-	id := infra.GetUniqueName()
+	id := opts.Infra.GetUniqueName()
 
 	prov := &provisioner.Conf{
 		ID:                  id,
-		Name:                fmt.Sprintf("prov-%s-%s", id, string(operation)),
-		Operation:           operation,
+		Name:                fmt.Sprintf("prov-%s-%s", id, string(opts.Operation)),
+		Operation:           opts.Operation,
 		Kind:                provisioner.Test,
-		Redis:               redisConf,
-		Postgres:            pgConf,
-		ProvisionerImageTag: provImageTag,
-		ImagePullSecret:     provImagePullSecret,
+		Redis:               opts.RedisConf,
+		Postgres:            opts.PGConf,
+		ProvisionerImageTag: opts.ProvImageTag,
+		ImagePullSecret:     opts.ProvImagePullSecret,
 	}
 
-	return a.provision(prov, infra, repo)
+	return a.provision(prov, opts.Infra, opts.Repo)
 }
 
 func (a *Agent) provision(