소스 검색

update provisioning with destroy handling

Alexander Belanger 5 년 전
부모
커밋
d74c0a7724

+ 50 - 46
internal/kubernetes/agent.go

@@ -250,13 +250,14 @@ func (a *Agent) ProvisionECR(
 	projectID uint,
 	projectID uint,
 	awsConf *integrations.AWSIntegration,
 	awsConf *integrations.AWSIntegration,
 	ecrName string,
 	ecrName string,
+	repo repository.Repository,
 	infra *models.Infra,
 	infra *models.Infra,
 	operation provisioner.ProvisionerOperation,
 	operation provisioner.ProvisionerOperation,
 	pgConf *config.DBConf,
 	pgConf *config.DBConf,
 	redisConf *config.RedisConf,
 	redisConf *config.RedisConf,
 	provImageTag string,
 	provImageTag string,
 ) (*batchv1.Job, error) {
 ) (*batchv1.Job, error) {
-	id := infra.GetID()
+	id := infra.GetUniqueName()
 	prov := &provisioner.Conf{
 	prov := &provisioner.Conf{
 		ID:                  id,
 		ID:                  id,
 		Name:                fmt.Sprintf("prov-%s-%s", id, string(operation)),
 		Name:                fmt.Sprintf("prov-%s-%s", id, string(operation)),
@@ -265,6 +266,7 @@ func (a *Agent) ProvisionECR(
 		Redis:               redisConf,
 		Redis:               redisConf,
 		Postgres:            pgConf,
 		Postgres:            pgConf,
 		ProvisionerImageTag: provImageTag,
 		ProvisionerImageTag: provImageTag,
+		LastApplied:         infra.LastApplied,
 		AWS: &aws.Conf{
 		AWS: &aws.Conf{
 			AWSRegion:          awsConf.AWSRegion,
 			AWSRegion:          awsConf.AWSRegion,
 			AWSAccessKeyID:     string(awsConf.AWSAccessKeyID),
 			AWSAccessKeyID:     string(awsConf.AWSAccessKeyID),
@@ -275,7 +277,7 @@ func (a *Agent) ProvisionECR(
 		},
 		},
 	}
 	}
 
 
-	return a.provision(prov)
+	return a.provision(prov, infra, repo)
 }
 }
 
 
 // ProvisionEKS spawns a new provisioning pod that creates an EKS instance
 // ProvisionEKS spawns a new provisioning pod that creates an EKS instance
@@ -283,13 +285,14 @@ func (a *Agent) ProvisionEKS(
 	projectID uint,
 	projectID uint,
 	awsConf *integrations.AWSIntegration,
 	awsConf *integrations.AWSIntegration,
 	eksName string,
 	eksName string,
+	repo repository.Repository,
 	infra *models.Infra,
 	infra *models.Infra,
 	operation provisioner.ProvisionerOperation,
 	operation provisioner.ProvisionerOperation,
 	pgConf *config.DBConf,
 	pgConf *config.DBConf,
 	redisConf *config.RedisConf,
 	redisConf *config.RedisConf,
 	provImageTag string,
 	provImageTag string,
 ) (*batchv1.Job, error) {
 ) (*batchv1.Job, error) {
-	id := infra.GetID()
+	id := infra.GetUniqueName()
 	prov := &provisioner.Conf{
 	prov := &provisioner.Conf{
 		ID:                  id,
 		ID:                  id,
 		Name:                fmt.Sprintf("prov-%s-%s", id, string(operation)),
 		Name:                fmt.Sprintf("prov-%s-%s", id, string(operation)),
@@ -298,6 +301,7 @@ func (a *Agent) ProvisionEKS(
 		Redis:               redisConf,
 		Redis:               redisConf,
 		Postgres:            pgConf,
 		Postgres:            pgConf,
 		ProvisionerImageTag: provImageTag,
 		ProvisionerImageTag: provImageTag,
+		LastApplied:         infra.LastApplied,
 		AWS: &aws.Conf{
 		AWS: &aws.Conf{
 			AWSRegion:          awsConf.AWSRegion,
 			AWSRegion:          awsConf.AWSRegion,
 			AWSAccessKeyID:     string(awsConf.AWSAccessKeyID),
 			AWSAccessKeyID:     string(awsConf.AWSAccessKeyID),
@@ -308,20 +312,21 @@ func (a *Agent) ProvisionEKS(
 		},
 		},
 	}
 	}
 
 
-	return a.provision(prov)
+	return a.provision(prov, infra, repo)
 }
 }
 
 
 // ProvisionGCR spawns a new provisioning pod that creates a GCR instance
 // ProvisionGCR spawns a new provisioning pod that creates a GCR instance
 func (a *Agent) ProvisionGCR(
 func (a *Agent) ProvisionGCR(
 	projectID uint,
 	projectID uint,
 	gcpConf *integrations.GCPIntegration,
 	gcpConf *integrations.GCPIntegration,
+	repo repository.Repository,
 	infra *models.Infra,
 	infra *models.Infra,
 	operation provisioner.ProvisionerOperation,
 	operation provisioner.ProvisionerOperation,
 	pgConf *config.DBConf,
 	pgConf *config.DBConf,
 	redisConf *config.RedisConf,
 	redisConf *config.RedisConf,
 	provImageTag string,
 	provImageTag string,
 ) (*batchv1.Job, error) {
 ) (*batchv1.Job, error) {
-	id := infra.GetID()
+	id := infra.GetUniqueName()
 	prov := &provisioner.Conf{
 	prov := &provisioner.Conf{
 		ID:                  id,
 		ID:                  id,
 		Name:                fmt.Sprintf("prov-%s-%s", id, string(operation)),
 		Name:                fmt.Sprintf("prov-%s-%s", id, string(operation)),
@@ -330,6 +335,7 @@ func (a *Agent) ProvisionGCR(
 		Redis:               redisConf,
 		Redis:               redisConf,
 		Postgres:            pgConf,
 		Postgres:            pgConf,
 		ProvisionerImageTag: provImageTag,
 		ProvisionerImageTag: provImageTag,
+		LastApplied:         infra.LastApplied,
 		GCP: &gcp.Conf{
 		GCP: &gcp.Conf{
 			GCPRegion:    gcpConf.GCPRegion,
 			GCPRegion:    gcpConf.GCPRegion,
 			GCPProjectID: gcpConf.GCPProjectID,
 			GCPProjectID: gcpConf.GCPProjectID,
@@ -337,7 +343,7 @@ func (a *Agent) ProvisionGCR(
 		},
 		},
 	}
 	}
 
 
-	return a.provision(prov)
+	return a.provision(prov, infra, repo)
 }
 }
 
 
 // ProvisionGKE spawns a new provisioning pod that creates a GKE instance
 // ProvisionGKE spawns a new provisioning pod that creates a GKE instance
@@ -345,13 +351,14 @@ func (a *Agent) ProvisionGKE(
 	projectID uint,
 	projectID uint,
 	gcpConf *integrations.GCPIntegration,
 	gcpConf *integrations.GCPIntegration,
 	gkeName string,
 	gkeName string,
+	repo repository.Repository,
 	infra *models.Infra,
 	infra *models.Infra,
 	operation provisioner.ProvisionerOperation,
 	operation provisioner.ProvisionerOperation,
 	pgConf *config.DBConf,
 	pgConf *config.DBConf,
 	redisConf *config.RedisConf,
 	redisConf *config.RedisConf,
 	provImageTag string,
 	provImageTag string,
 ) (*batchv1.Job, error) {
 ) (*batchv1.Job, error) {
-	id := infra.GetID()
+	id := infra.GetUniqueName()
 	prov := &provisioner.Conf{
 	prov := &provisioner.Conf{
 		ID:                  id,
 		ID:                  id,
 		Name:                fmt.Sprintf("prov-%s-%s", id, string(operation)),
 		Name:                fmt.Sprintf("prov-%s-%s", id, string(operation)),
@@ -360,6 +367,7 @@ func (a *Agent) ProvisionGKE(
 		Redis:               redisConf,
 		Redis:               redisConf,
 		Postgres:            pgConf,
 		Postgres:            pgConf,
 		ProvisionerImageTag: provImageTag,
 		ProvisionerImageTag: provImageTag,
+		LastApplied:         infra.LastApplied,
 		GCP: &gcp.Conf{
 		GCP: &gcp.Conf{
 			GCPRegion:    gcpConf.GCPRegion,
 			GCPRegion:    gcpConf.GCPRegion,
 			GCPProjectID: gcpConf.GCPProjectID,
 			GCPProjectID: gcpConf.GCPProjectID,
@@ -370,7 +378,7 @@ func (a *Agent) ProvisionGKE(
 		},
 		},
 	}
 	}
 
 
-	return a.provision(prov)
+	return a.provision(prov, infra, repo)
 }
 }
 
 
 // ProvisionDOCR spawns a new provisioning pod that creates a DOCR instance
 // ProvisionDOCR spawns a new provisioning pod that creates a DOCR instance
@@ -400,14 +408,15 @@ func (a *Agent) ProvisionDOCR(
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	id := infra.GetID()
+	id := infra.GetUniqueName()
 	prov := &provisioner.Conf{
 	prov := &provisioner.Conf{
-		ID:        id,
-		Name:      fmt.Sprintf("prov-%s-%s", id, string(operation)),
-		Kind:      provisioner.DOCR,
-		Operation: operation,
-		Redis:     redisConf,
-		Postgres:  pgConf,
+		ID:          id,
+		Name:        fmt.Sprintf("prov-%s-%s", id, string(operation)),
+		Kind:        provisioner.DOCR,
+		Operation:   operation,
+		Redis:       redisConf,
+		Postgres:    pgConf,
+		LastApplied: infra.LastApplied,
 		DO: &do.Conf{
 		DO: &do.Conf{
 			DOToken: tok,
 			DOToken: tok,
 		},
 		},
@@ -417,7 +426,7 @@ func (a *Agent) ProvisionDOCR(
 		},
 		},
 	}
 	}
 
 
-	return a.provision(prov)
+	return a.provision(prov, infra, repo)
 }
 }
 
 
 // ProvisionDOKS spawns a new provisioning pod that creates a DOKS instance
 // ProvisionDOKS spawns a new provisioning pod that creates a DOKS instance
@@ -447,14 +456,15 @@ func (a *Agent) ProvisionDOKS(
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	id := infra.GetID()
+	id := infra.GetUniqueName()
 	prov := &provisioner.Conf{
 	prov := &provisioner.Conf{
-		ID:        id,
-		Name:      fmt.Sprintf("prov-%s-%s", id, string(operation)),
-		Kind:      provisioner.DOKS,
-		Operation: operation,
-		Redis:     redisConf,
-		Postgres:  pgConf,
+		ID:          id,
+		Name:        fmt.Sprintf("prov-%s-%s", id, string(operation)),
+		Kind:        provisioner.DOKS,
+		Operation:   operation,
+		Redis:       redisConf,
+		Postgres:    pgConf,
+		LastApplied: infra.LastApplied,
 		DO: &do.Conf{
 		DO: &do.Conf{
 			DOToken: tok,
 			DOToken: tok,
 		},
 		},
@@ -464,32 +474,13 @@ func (a *Agent) ProvisionDOKS(
 		},
 		},
 	}
 	}
 
 
-	return a.provision(prov)
-}
-
-// ProvisionTest spawns a new provisioning pod that tests provisioning
-func (a *Agent) ProvisionTest(
-	projectID uint,
-	operation provisioner.ProvisionerOperation,
-	pgConf *config.DBConf,
-	redisConf *config.RedisConf,
-	provImageTag string,
-) (*batchv1.Job, error) {
-	prov := &provisioner.Conf{
-		ID:                  fmt.Sprintf("%s-%d", "testing", projectID),
-		Name:                fmt.Sprintf("prov-%s-%d-%s", "testing", projectID, string(operation)),
-		Operation:           operation,
-		Kind:                provisioner.Test,
-		Redis:               redisConf,
-		Postgres:            pgConf,
-		ProvisionerImageTag: provImageTag,
-	}
-
-	return a.provision(prov)
+	return a.provision(prov, infra, repo)
 }
 }
 
 
 func (a *Agent) provision(
 func (a *Agent) provision(
 	prov *provisioner.Conf,
 	prov *provisioner.Conf,
+	infra *models.Infra,
+	repo repository.Repository,
 ) (*batchv1.Job, error) {
 ) (*batchv1.Job, error) {
 	prov.Namespace = "default"
 	prov.Namespace = "default"
 
 
@@ -499,11 +490,24 @@ func (a *Agent) provision(
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	return a.Clientset.BatchV1().Jobs(prov.Namespace).Create(
+	job, err = a.Clientset.BatchV1().Jobs(prov.Namespace).Create(
 		context.TODO(),
 		context.TODO(),
 		job,
 		job,
 		metav1.CreateOptions{},
 		metav1.CreateOptions{},
 	)
 	)
+
+	if err != nil {
+		return nil, err
+	}
+
+	infra.LastApplied = prov.LastApplied
+	infra, err = repo.Infra.UpdateInfra(infra)
+
+	if err != nil {
+		return nil, err
+	}
+
+	return job, nil
 }
 }
 
 
 // CreateImagePullSecrets will create the required image pull secrets and
 // CreateImagePullSecrets will create the required image pull secrets and

+ 1 - 1
internal/kubernetes/provisioner/global_stream.go

@@ -111,7 +111,7 @@ func GlobalStreamListener(
 		// parse messages from the global stream
 		// parse messages from the global stream
 		for _, msg := range xstreams[0].Messages {
 		for _, msg := range xstreams[0].Messages {
 			// parse the id to identify the infra
 			// parse the id to identify the infra
-			kind, projID, infraID, err := models.ParseWorkspaceID(fmt.Sprintf("%v", msg.Values["id"]))
+			kind, projID, infraID, err := models.ParseUniqueName(fmt.Sprintf("%v", msg.Values["id"]))
 
 
 			if fmt.Sprintf("%v", msg.Values["status"]) == "created" {
 			if fmt.Sprintf("%v", msg.Values["status"]) == "created" {
 				infra, err := repo.Infra.ReadInfra(infraID)
 				infra, err := repo.Infra.ReadInfra(infraID)

+ 23 - 0
internal/kubernetes/provisioner/input/docr.go

@@ -0,0 +1,23 @@
+package input
+
+import (
+	"encoding/json"
+)
+
+type DOCR struct {
+	DOToken              string `json:"do_token"`
+	DOCRName             string `json:"docr_name"`
+	DOCRSubscriptionTier string `json:"docr_subscription_tier"`
+}
+
+func (docr *DOCR) GetInput() ([]byte, error) {
+	return json.Marshal(docr)
+}
+
+func GetDOCRInput(bytes []byte) (*DOCR, error) {
+	res := &DOCR{}
+
+	err := json.Unmarshal(bytes, res)
+
+	return res, err
+}

+ 23 - 0
internal/kubernetes/provisioner/input/doks.go

@@ -0,0 +1,23 @@
+package input
+
+import (
+	"encoding/json"
+)
+
+type DOKS struct {
+	DORegion    string `json:"do_region"`
+	DOToken     string `json:"do_token"`
+	ClusterName string `json:"cluster_name"`
+}
+
+func (doks *DOKS) GetInput() ([]byte, error) {
+	return json.Marshal(doks)
+}
+
+func GetDOKSInput(bytes []byte) (*DOKS, error) {
+	res := &DOKS{}
+
+	err := json.Unmarshal(bytes, res)
+
+	return res, err
+}

+ 24 - 0
internal/kubernetes/provisioner/input/ecr.go

@@ -0,0 +1,24 @@
+package input
+
+import (
+	"encoding/json"
+)
+
+type ECR struct {
+	AWSRegion    string `json:"aws_region"`
+	AWSAccessKey string `json:"aws_access_key"`
+	AWSSecretKey string `json:"aws_secret_key"`
+	ECRName      string `json:"ecr_name"`
+}
+
+func (ecr *ECR) GetInput() ([]byte, error) {
+	return json.Marshal(ecr)
+}
+
+func GetECRInput(bytes []byte) (*ECR, error) {
+	res := &ECR{}
+
+	err := json.Unmarshal(bytes, res)
+
+	return res, err
+}

+ 24 - 0
internal/kubernetes/provisioner/input/eks.go

@@ -0,0 +1,24 @@
+package input
+
+import (
+	"encoding/json"
+)
+
+type EKS struct {
+	AWSRegion    string `json:"aws_region"`
+	AWSAccessKey string `json:"aws_access_key"`
+	AWSSecretKey string `json:"aws_secret_key"`
+	ClusterName  string `json:"cluster_name"`
+}
+
+func (eks *EKS) GetInput() ([]byte, error) {
+	return json.Marshal(eks)
+}
+
+func GetEKSInput(bytes []byte) (*EKS, error) {
+	res := &EKS{}
+
+	err := json.Unmarshal(bytes, res)
+
+	return res, err
+}

+ 23 - 0
internal/kubernetes/provisioner/input/gcr.go

@@ -0,0 +1,23 @@
+package input
+
+import (
+	"encoding/json"
+)
+
+type GCR struct {
+	GCPCredentials string `json:"gcp_credentials"`
+	GCPRegion      string `json:"gcp_region"`
+	GCPProjectID   string `json:"gcp_project_id"`
+}
+
+func (gcr *GCR) GetInput() ([]byte, error) {
+	return json.Marshal(gcr)
+}
+
+func GetGCRInput(bytes []byte) (*GCR, error) {
+	res := &GCR{}
+
+	err := json.Unmarshal(bytes, res)
+
+	return res, err
+}

+ 24 - 0
internal/kubernetes/provisioner/input/gke.go

@@ -0,0 +1,24 @@
+package input
+
+import (
+	"encoding/json"
+)
+
+type GKE struct {
+	GCPCredentials string `json:"gcp_credentials"`
+	GCPRegion      string `json:"gcp_region"`
+	GCPProjectID   string `json:"gcp_project_id"`
+	ClusterName    string `json:"cluster_name"`
+}
+
+func (gke *GKE) GetInput() ([]byte, error) {
+	return json.Marshal(gke)
+}
+
+func GetGKEInput(bytes []byte) (*GKE, error) {
+	res := &GKE{}
+
+	err := json.Unmarshal(bytes, res)
+
+	return res, err
+}

+ 178 - 14
internal/kubernetes/provisioner/provisioner.go

@@ -13,6 +13,7 @@ import (
 	"github.com/porter-dev/porter/internal/kubernetes/provisioner/do"
 	"github.com/porter-dev/porter/internal/kubernetes/provisioner/do"
 	"github.com/porter-dev/porter/internal/kubernetes/provisioner/do/docr"
 	"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/do/doks"
+	"github.com/porter-dev/porter/internal/kubernetes/provisioner/input"
 
 
 	"github.com/porter-dev/porter/internal/kubernetes/provisioner/gcp"
 	"github.com/porter-dev/porter/internal/kubernetes/provisioner/gcp"
 	"github.com/porter-dev/porter/internal/kubernetes/provisioner/gcp/gke"
 	"github.com/porter-dev/porter/internal/kubernetes/provisioner/gcp/gke"
@@ -25,7 +26,6 @@ type InfraOption string
 
 
 // The list of infra options
 // The list of infra options
 const (
 const (
-	Test InfraOption = "test"
 	ECR  InfraOption = "ecr"
 	ECR  InfraOption = "ecr"
 	EKS  InfraOption = "eks"
 	EKS  InfraOption = "eks"
 	GCR  InfraOption = "gcr"
 	GCR  InfraOption = "gcr"
@@ -44,6 +44,7 @@ type Conf struct {
 	Postgres            *config.DBConf
 	Postgres            *config.DBConf
 	Operation           ProvisionerOperation
 	Operation           ProvisionerOperation
 	ProvisionerImageTag string
 	ProvisionerImageTag string
+	LastApplied         []byte
 
 
 	// provider-specific configurations
 	// provider-specific configurations
 
 
@@ -84,11 +85,7 @@ func (conf *Conf) GetProvisionerJobTemplate() (*batchv1.Job, error) {
 
 
 	ttl := int32(3600)
 	ttl := int32(3600)
 
 
-	backoffLimit := int32(5)
-
-	if operation == string(Apply) {
-		backoffLimit = int32(1)
-	}
+	backoffLimit := int32(1)
 
 
 	labels := map[string]string{
 	labels := map[string]string{
 		"app": "provisioner",
 		"app": "provisioner",
@@ -96,29 +93,196 @@ func (conf *Conf) GetProvisionerJobTemplate() (*batchv1.Job, error) {
 
 
 	args := make([]string, 0)
 	args := make([]string, 0)
 
 
-	if conf.Kind == Test {
-		args = []string{operation, "test", "hello"}
-	} else if conf.Kind == ECR {
+	switch conf.Kind {
+	case ECR:
 		args = []string{operation, "ecr"}
 		args = []string{operation, "ecr"}
+
+		if len(conf.LastApplied) > 0 {
+			inputConf, err := input.GetECRInput(conf.LastApplied)
+
+			if err != nil {
+				return nil, err
+			}
+
+			conf.AWS.AWSAccessKeyID = inputConf.AWSAccessKey
+			conf.AWS.AWSSecretAccessKey = inputConf.AWSSecretKey
+			conf.AWS.AWSRegion = inputConf.AWSRegion
+			conf.ECR.ECRName = inputConf.ECRName
+		} else {
+			inputConf := &input.ECR{
+				AWSRegion:    conf.AWS.AWSRegion,
+				AWSAccessKey: conf.AWS.AWSAccessKeyID,
+				AWSSecretKey: conf.AWS.AWSSecretAccessKey,
+				ECRName:      conf.ECR.ECRName,
+			}
+
+			lastApplied, err := inputConf.GetInput()
+
+			if err != nil {
+				return nil, err
+			}
+
+			conf.LastApplied = lastApplied
+		}
+
 		env = conf.AWS.AttachAWSEnv(env)
 		env = conf.AWS.AttachAWSEnv(env)
 		env = conf.ECR.AttachECREnv(env)
 		env = conf.ECR.AttachECREnv(env)
-	} else if conf.Kind == EKS {
+	case EKS:
 		args = []string{operation, "eks"}
 		args = []string{operation, "eks"}
+
+		if len(conf.LastApplied) > 0 {
+			inputConf, err := input.GetEKSInput(conf.LastApplied)
+
+			if err != nil {
+				return nil, err
+			}
+
+			conf.AWS.AWSAccessKeyID = inputConf.AWSAccessKey
+			conf.AWS.AWSSecretAccessKey = inputConf.AWSSecretKey
+			conf.AWS.AWSRegion = inputConf.AWSRegion
+			conf.EKS.ClusterName = inputConf.ClusterName
+		} else {
+			inputConf := &input.EKS{
+				AWSRegion:    conf.AWS.AWSRegion,
+				AWSAccessKey: conf.AWS.AWSAccessKeyID,
+				AWSSecretKey: conf.AWS.AWSSecretAccessKey,
+				ClusterName:  conf.EKS.ClusterName,
+			}
+
+			lastApplied, err := inputConf.GetInput()
+
+			if err != nil {
+				return nil, err
+			}
+
+			conf.LastApplied = lastApplied
+		}
+
 		env = conf.AWS.AttachAWSEnv(env)
 		env = conf.AWS.AttachAWSEnv(env)
 		env = conf.EKS.AttachEKSEnv(env)
 		env = conf.EKS.AttachEKSEnv(env)
-	} else if conf.Kind == GCR {
+	case GCR:
 		args = []string{operation, "gcr"}
 		args = []string{operation, "gcr"}
+
+		if len(conf.LastApplied) > 0 {
+			inputConf, err := input.GetGCRInput(conf.LastApplied)
+
+			if err != nil {
+				return nil, err
+			}
+
+			conf.GCP.GCPKeyData = inputConf.GCPCredentials
+			conf.GCP.GCPRegion = inputConf.GCPRegion
+			conf.GCP.GCPProjectID = inputConf.GCPProjectID
+		} else {
+			inputConf := &input.GCR{
+				GCPCredentials: conf.GCP.GCPKeyData,
+				GCPRegion:      conf.GCP.GCPRegion,
+				GCPProjectID:   conf.GCP.GCPProjectID,
+			}
+
+			lastApplied, err := inputConf.GetInput()
+
+			if err != nil {
+				return nil, err
+			}
+
+			conf.LastApplied = lastApplied
+		}
+
 		env = conf.GCP.AttachGCPEnv(env)
 		env = conf.GCP.AttachGCPEnv(env)
-	} else if conf.Kind == GKE {
+	case GKE:
 		args = []string{operation, "gke"}
 		args = []string{operation, "gke"}
+
+		if len(conf.LastApplied) > 0 {
+			inputConf, err := input.GetGKEInput(conf.LastApplied)
+
+			if err != nil {
+				return nil, err
+			}
+
+			conf.GCP.GCPKeyData = inputConf.GCPCredentials
+			conf.GCP.GCPRegion = inputConf.GCPRegion
+			conf.GCP.GCPProjectID = inputConf.GCPProjectID
+			conf.GKE.ClusterName = inputConf.ClusterName
+		} else {
+			inputConf := &input.GKE{
+				GCPCredentials: conf.GCP.GCPKeyData,
+				GCPRegion:      conf.GCP.GCPRegion,
+				GCPProjectID:   conf.GCP.GCPProjectID,
+				ClusterName:    conf.GKE.ClusterName,
+			}
+
+			lastApplied, err := inputConf.GetInput()
+
+			if err != nil {
+				return nil, err
+			}
+
+			conf.LastApplied = lastApplied
+		}
+
 		env = conf.GCP.AttachGCPEnv(env)
 		env = conf.GCP.AttachGCPEnv(env)
 		env = conf.GKE.AttachGKEEnv(env)
 		env = conf.GKE.AttachGKEEnv(env)
-	} else if conf.Kind == DOCR {
+	case DOCR:
 		args = []string{operation, "docr"}
 		args = []string{operation, "docr"}
+
+		if len(conf.LastApplied) > 0 {
+			inputConf, err := input.GetDOCRInput(conf.LastApplied)
+
+			if err != nil {
+				return nil, err
+			}
+
+			conf.DO.DOToken = inputConf.DOToken
+			conf.DOCR.DOCRSubscriptionTier = inputConf.DOCRSubscriptionTier
+			conf.DOCR.DOCRName = inputConf.DOCRName
+		} else {
+			inputConf := &input.DOCR{
+				DOToken:              conf.DO.DOToken,
+				DOCRSubscriptionTier: conf.DOCR.DOCRSubscriptionTier,
+				DOCRName:             conf.DOCR.DOCRName,
+			}
+
+			lastApplied, err := inputConf.GetInput()
+
+			if err != nil {
+				return nil, err
+			}
+
+			conf.LastApplied = lastApplied
+		}
+
 		env = conf.DO.AttachDOEnv(env)
 		env = conf.DO.AttachDOEnv(env)
 		env = conf.DOCR.AttachDOCREnv(env)
 		env = conf.DOCR.AttachDOCREnv(env)
-	} else if conf.Kind == GKE {
+	case DOKS:
 		args = []string{operation, "doks"}
 		args = []string{operation, "doks"}
+
+		if len(conf.LastApplied) > 0 {
+			inputConf, err := input.GetDOKSInput(conf.LastApplied)
+
+			if err != nil {
+				return nil, err
+			}
+
+			conf.DO.DOToken = inputConf.DOToken
+			conf.DOKS.DORegion = inputConf.DORegion
+			conf.DOKS.DOKSClusterName = inputConf.ClusterName
+		} else {
+			inputConf := &input.DOKS{
+				DOToken:     conf.DO.DOToken,
+				DORegion:    conf.DOKS.DORegion,
+				ClusterName: conf.DOKS.DOKSClusterName,
+			}
+
+			lastApplied, err := inputConf.GetInput()
+
+			if err != nil {
+				return nil, err
+			}
+
+			conf.LastApplied = lastApplied
+		}
+
 		env = conf.DO.AttachDOEnv(env)
 		env = conf.DO.AttachDOEnv(env)
 		env = conf.DOKS.AttachDOKSEnv(env)
 		env = conf.DOKS.AttachDOKSEnv(env)
 	}
 	}

+ 10 - 3
internal/models/infra.go

@@ -59,6 +59,13 @@ type Infra struct {
 	// The DO integration that was used to create the infra:
 	// The DO integration that was used to create the infra:
 	// this points to an OAuthIntegrationID
 	// this points to an OAuthIntegrationID
 	DOIntegrationID uint
 	DOIntegrationID uint
+
+	// ------------------------------------------------------------------
+	// All fields below this line are encrypted before storage
+	// ------------------------------------------------------------------
+
+	// The last-applied input variables to the provisioner
+	LastApplied []byte
 }
 }
 
 
 // InfraExternal is an external Infra to be shared over REST
 // InfraExternal is an external Infra to be shared over REST
@@ -86,12 +93,12 @@ func (i *Infra) Externalize() *InfraExternal {
 }
 }
 
 
 // GetID returns the unique id for this infra
 // GetID returns the unique id for this infra
-func (i *Infra) GetID() string {
+func (i *Infra) GetUniqueName() string {
 	return fmt.Sprintf("%s-%d-%d-%s", i.Kind, i.ProjectID, i.ID, i.Suffix)
 	return fmt.Sprintf("%s-%d-%d-%s", i.Kind, i.ProjectID, i.ID, i.Suffix)
 }
 }
 
 
-// ParseWorkspaceID returns the (kind, projectID, infraID)
-func ParseWorkspaceID(workspaceID string) (string, uint, uint, error) {
+// ParseUniqueName returns the (kind, projectID, infraID, suffix)
+func ParseUniqueName(workspaceID string) (string, uint, uint, error) {
 	strArr := strings.Split(workspaceID, "-")
 	strArr := strings.Split(workspaceID, "-")
 
 
 	if len(strArr) < 3 {
 	if len(strArr) < 3 {

+ 80 - 3
internal/repository/gorm/infra.go

@@ -1,6 +1,8 @@
 package gorm
 package gorm
 
 
 import (
 import (
+	"fmt"
+
 	"github.com/porter-dev/porter/internal/models"
 	"github.com/porter-dev/porter/internal/models"
 	"github.com/porter-dev/porter/internal/repository"
 	"github.com/porter-dev/porter/internal/repository"
 	"gorm.io/gorm"
 	"gorm.io/gorm"
@@ -8,17 +10,24 @@ import (
 
 
 // InfraRepository uses gorm.DB for querying the database
 // InfraRepository uses gorm.DB for querying the database
 type InfraRepository struct {
 type InfraRepository struct {
-	db *gorm.DB
+	db  *gorm.DB
+	key *[32]byte
 }
 }
 
 
 // NewInfraRepository returns a InfraRepository which uses
 // NewInfraRepository returns a InfraRepository which uses
 // gorm.DB for querying the database
 // gorm.DB for querying the database
-func NewInfraRepository(db *gorm.DB) repository.InfraRepository {
-	return &InfraRepository{db}
+func NewInfraRepository(db *gorm.DB, key *[32]byte) repository.InfraRepository {
+	return &InfraRepository{db, key}
 }
 }
 
 
 // CreateInfra creates a new aws infra
 // CreateInfra creates a new aws infra
 func (repo *InfraRepository) CreateInfra(infra *models.Infra) (*models.Infra, error) {
 func (repo *InfraRepository) CreateInfra(infra *models.Infra) (*models.Infra, error) {
+	err := repo.EncryptInfraData(infra, repo.key)
+
+	if err != nil {
+		return nil, err
+	}
+
 	project := &models.Project{}
 	project := &models.Project{}
 
 
 	if err := repo.db.Where("id = ?", infra.ProjectID).First(&project).Error; err != nil {
 	if err := repo.db.Where("id = ?", infra.ProjectID).First(&project).Error; err != nil {
@@ -35,6 +44,12 @@ func (repo *InfraRepository) CreateInfra(infra *models.Infra) (*models.Infra, er
 		return nil, err
 		return nil, err
 	}
 	}
 
 
+	err = repo.DecryptInfraData(infra, repo.key)
+
+	if err != nil {
+		return nil, err
+	}
+
 	return infra, nil
 	return infra, nil
 }
 }
 
 
@@ -46,6 +61,14 @@ func (repo *InfraRepository) ReadInfra(id uint) (*models.Infra, error) {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
+	fmt.Println("INNFRA LAST APPLIED", string(infra.LastApplied))
+
+	err := repo.DecryptInfraData(infra, repo.key)
+
+	if err != nil {
+		return nil, err
+	}
+
 	return infra, nil
 	return infra, nil
 }
 }
 
 
@@ -60,6 +83,10 @@ func (repo *InfraRepository) ListInfrasByProjectID(
 		return nil, err
 		return nil, err
 	}
 	}
 
 
+	for _, infra := range infras {
+		repo.DecryptInfraData(infra, repo.key)
+	}
+
 	return infras, nil
 	return infras, nil
 }
 }
 
 
@@ -67,9 +94,59 @@ func (repo *InfraRepository) ListInfrasByProjectID(
 func (repo *InfraRepository) UpdateInfra(
 func (repo *InfraRepository) UpdateInfra(
 	ai *models.Infra,
 	ai *models.Infra,
 ) (*models.Infra, error) {
 ) (*models.Infra, error) {
+	err := repo.EncryptInfraData(ai, repo.key)
+
+	if err != nil {
+		return nil, err
+	}
+
 	if err := repo.db.Save(ai).Error; err != nil {
 	if err := repo.db.Save(ai).Error; err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
+	err = repo.DecryptInfraData(ai, repo.key)
+
+	if err != nil {
+		return nil, err
+	}
+
 	return ai, nil
 	return ai, nil
 }
 }
+
+// EncryptInfraData will encrypt the infra data before
+// writing to the DB
+func (repo *InfraRepository) EncryptInfraData(
+	infra *models.Infra,
+	key *[32]byte,
+) error {
+	if len(infra.LastApplied) > 0 {
+		cipherData, err := repository.Encrypt(infra.LastApplied, key)
+
+		if err != nil {
+			return err
+		}
+
+		infra.LastApplied = cipherData
+	}
+
+	return nil
+}
+
+// DecryptInfraData will decrypt the user's infra data before
+// returning it from the DB
+func (repo *InfraRepository) DecryptInfraData(
+	infra *models.Infra,
+	key *[32]byte,
+) error {
+	if len(infra.LastApplied) > 0 {
+		plaintext, err := repository.Decrypt(infra.LastApplied, key)
+
+		if err != nil {
+			return err
+		}
+
+		infra.LastApplied = plaintext
+	}
+
+	return nil
+}

+ 1 - 1
internal/repository/gorm/repository.go

@@ -17,7 +17,7 @@ func NewRepository(db *gorm.DB, key *[32]byte) *repository.Repository {
 		Cluster:          NewClusterRepository(db, key),
 		Cluster:          NewClusterRepository(db, key),
 		HelmRepo:         NewHelmRepoRepository(db, key),
 		HelmRepo:         NewHelmRepoRepository(db, key),
 		Registry:         NewRegistryRepository(db, key),
 		Registry:         NewRegistryRepository(db, key),
-		Infra:         NewInfraRepository(db),
+		Infra:            NewInfraRepository(db, key),
 		KubeIntegration:  NewKubeIntegrationRepository(db, key),
 		KubeIntegration:  NewKubeIntegrationRepository(db, key),
 		BasicIntegration: NewBasicIntegrationRepository(db, key),
 		BasicIntegration: NewBasicIntegrationRepository(db, key),
 		OIDCIntegration:  NewOIDCIntegrationRepository(db, key),
 		OIDCIntegration:  NewOIDCIntegrationRepository(db, key),

+ 1 - 1
server/api/oauth_github_handler.go

@@ -183,7 +183,7 @@ func (app *App) updateProjectFromToken(projectID uint, userID uint, tok *oauth2.
 	// create the git repo
 	// create the git repo
 	gr := &models.GitRepo{
 	gr := &models.GitRepo{
 		ProjectID:          projectID,
 		ProjectID:          projectID,
-		RepoEntity:         *user.Name,
+		RepoEntity:         *user.Login,
 		OAuthIntegrationID: oauthInt.ID,
 		OAuthIntegrationID: oauthInt.ID,
 	}
 	}
 
 

+ 8 - 35
server/api/provision_handler.go

@@ -15,40 +15,6 @@ import (
 	"github.com/porter-dev/porter/internal/adapter"
 	"github.com/porter-dev/porter/internal/adapter"
 )
 )
 
 
-// HandleProvisionTest will create a test resource by deploying a provisioner
-// container pod
-func (app *App) HandleProvisionTest(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
-	}
-
-	// create a new agent
-	agent, err := kubernetes.GetAgentInClusterConfig()
-
-	if err != nil {
-		app.handleErrorDataRead(err, w)
-		return
-	}
-
-	_, err = agent.ProvisionTest(
-		uint(projID),
-		provisioner.Apply,
-		&app.DBConf,
-		app.RedisConf,
-		app.ServerConf.ProvisionerImageTag,
-	)
-
-	if err != nil {
-		app.handleErrorInternal(err, w)
-		return
-	}
-
-	w.WriteHeader(http.StatusOK)
-}
-
 // HandleProvisionAWSECRInfra provisions a new aws ECR instance for a project
 // HandleProvisionAWSECRInfra provisions a new aws ECR instance for a project
 func (app *App) HandleProvisionAWSECRInfra(w http.ResponseWriter, r *http.Request) {
 func (app *App) HandleProvisionAWSECRInfra(w http.ResponseWriter, r *http.Request) {
 	projID, err := strconv.ParseUint(chi.URLParam(r, "project_id"), 0, 64)
 	projID, err := strconv.ParseUint(chi.URLParam(r, "project_id"), 0, 64)
@@ -115,6 +81,7 @@ func (app *App) HandleProvisionAWSECRInfra(w http.ResponseWriter, r *http.Reques
 		uint(projID),
 		uint(projID),
 		awsInt,
 		awsInt,
 		form.ECRName,
 		form.ECRName,
+		*app.Repo,
 		infra,
 		infra,
 		provisioner.Apply,
 		provisioner.Apply,
 		&app.DBConf,
 		&app.DBConf,
@@ -206,6 +173,7 @@ func (app *App) HandleDestroyAWSECRInfra(w http.ResponseWriter, r *http.Request)
 		infra.ProjectID,
 		infra.ProjectID,
 		awsInt,
 		awsInt,
 		form.ECRName,
 		form.ECRName,
+		*app.Repo,
 		infra,
 		infra,
 		provisioner.Destroy,
 		provisioner.Destroy,
 		&app.DBConf,
 		&app.DBConf,
@@ -289,6 +257,7 @@ func (app *App) HandleProvisionAWSEKSInfra(w http.ResponseWriter, r *http.Reques
 		uint(projID),
 		uint(projID),
 		awsInt,
 		awsInt,
 		form.EKSName,
 		form.EKSName,
+		*app.Repo,
 		infra,
 		infra,
 		provisioner.Apply,
 		provisioner.Apply,
 		&app.DBConf,
 		&app.DBConf,
@@ -380,6 +349,7 @@ func (app *App) HandleDestroyAWSEKSInfra(w http.ResponseWriter, r *http.Request)
 		infra.ProjectID,
 		infra.ProjectID,
 		awsInt,
 		awsInt,
 		form.EKSName,
 		form.EKSName,
+		*app.Repo,
 		infra,
 		infra,
 		provisioner.Destroy,
 		provisioner.Destroy,
 		&app.DBConf,
 		&app.DBConf,
@@ -462,6 +432,7 @@ func (app *App) HandleProvisionGCPGCRInfra(w http.ResponseWriter, r *http.Reques
 	_, err = agent.ProvisionGCR(
 	_, err = agent.ProvisionGCR(
 		uint(projID),
 		uint(projID),
 		gcpInt,
 		gcpInt,
+		*app.Repo,
 		infra,
 		infra,
 		provisioner.Apply,
 		provisioner.Apply,
 		&app.DBConf,
 		&app.DBConf,
@@ -555,6 +526,7 @@ func (app *App) HandleProvisionGCPGKEInfra(w http.ResponseWriter, r *http.Reques
 		uint(projID),
 		uint(projID),
 		gcpInt,
 		gcpInt,
 		form.GKEName,
 		form.GKEName,
+		*app.Repo,
 		infra,
 		infra,
 		provisioner.Apply,
 		provisioner.Apply,
 		&app.DBConf,
 		&app.DBConf,
@@ -646,6 +618,7 @@ func (app *App) HandleDestroyGCPGKEInfra(w http.ResponseWriter, r *http.Request)
 		infra.ProjectID,
 		infra.ProjectID,
 		gcpInt,
 		gcpInt,
 		form.GKEName,
 		form.GKEName,
+		*app.Repo,
 		infra,
 		infra,
 		provisioner.Destroy,
 		provisioner.Destroy,
 		&app.DBConf,
 		&app.DBConf,
@@ -681,7 +654,7 @@ func (app *App) HandleGetProvisioningLogs(w http.ResponseWriter, r *http.Request
 		return
 		return
 	}
 	}
 
 
-	streamName := infra.GetID()
+	streamName := infra.GetUniqueName()
 
 
 	upgrader.CheckOrigin = func(r *http.Request) bool { return true }
 	upgrader.CheckOrigin = func(r *http.Request) bool { return true }
 
 

+ 0 - 10
server/router/router.go

@@ -205,16 +205,6 @@ func New(a *api.App) *chi.Mux {
 		)
 		)
 
 
 		// /api/projects/{project_id}/provision routes
 		// /api/projects/{project_id}/provision routes
-		r.Method(
-			"POST",
-			"/projects/{project_id}/provision/test",
-			auth.DoesUserHaveProjectAccess(
-				requestlog.NewHandler(a.HandleProvisionTest, l),
-				mw.URLParam,
-				mw.ReadAccess,
-			),
-		)
-
 		r.Method(
 		r.Method(
 			"POST",
 			"POST",
 			"/projects/{project_id}/provision/ecr",
 			"/projects/{project_id}/provision/ecr",