Explorar o código

add forms and optionality for s3

Alexander Belanger %!s(int64=4) %!d(string=hai) anos
pai
achega
537ffa975d

+ 4 - 0
api/server/handlers/infra/create.go

@@ -81,6 +81,8 @@ func (c *InfraCreateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		CreatedByUserID: user.ID,
 		SourceLink:      sourceLink,
 		SourceVersion:   sourceVersion,
+		// If the cluster ID was passed in, we store the parent cluster ID in the infra
+		// so it can be referenced later
 		ParentClusterID: req.ClusterID,
 	}
 
@@ -201,6 +203,8 @@ func getSourceLinkAndVersion(kind types.InfraKind) (string, string) {
 		return "porter/aws/eks", "v0.1.0"
 	case types.InfraRDS:
 		return "porter/aws/rds", "v0.1.0"
+	case types.InfraS3:
+		return "porter/aws/s3", "v0.1.0"
 	case types.InfraGCR:
 		return "porter/gcp/gcr", "v0.1.0"
 	case types.InfraGKE:

+ 21 - 0
api/server/handlers/infra/forms.go

@@ -18,6 +18,27 @@ tabs:
         default: hello
 `
 
+const s3Form = `name: S3
+hasSource: false
+includeHiddenFields: true
+isClusterScoped: true
+tabs:
+- name: main
+  label: Main
+  sections:
+  - name: heading
+    contents: 
+    - type: heading
+      label: S3 Settings
+  - name: bucket_name
+    contents:
+    - type: string-input
+      label: Bucket Name
+      required: true
+      placeholder: "s3-bucket-name"
+      variable: bucket_name
+`
+
 const rdsForm = `name: RDS
 hasSource: false
 includeHiddenFields: true

+ 2 - 0
api/server/handlers/infra/get_template.go

@@ -67,6 +67,8 @@ func getFormBytesFromKind(kind string) []byte {
 		formBytes = []byte(ecrForm)
 	case "rds":
 		formBytes = []byte(rdsForm)
+	case "s3":
+		formBytes = []byte(s3Form)
 	case "eks":
 		formBytes = []byte(eksForm)
 	case "gcr":

+ 8 - 0
api/server/handlers/infra/list_templates.go

@@ -57,6 +57,14 @@ var templateMap = map[string]*types.InfraTemplateMeta{
 		Kind:               "rds",
 		RequiredCredential: "aws_integration_id",
 	},
+	"s3": {
+		Icon:               "",
+		Description:        "Create an S3 bucket.",
+		Name:               "S3",
+		Version:            "v0.1.0",
+		Kind:               "s3",
+		RequiredCredential: "aws_integration_id",
+	},
 	"eks": {
 		Icon:               "https://img.stackshare.io/service/7991/amazon-eks.png",
 		Description:        "Create an Elastic Kubernetes Service cluster.",

+ 1 - 0
api/types/infra.go

@@ -30,6 +30,7 @@ const (
 	InfraACR  InfraKind = "acr"
 
 	InfraRDS InfraKind = "rds"
+	InfraS3  InfraKind = "s3"
 )
 
 type Infra struct {

+ 5 - 0
dashboard/src/shared/common.tsx

@@ -114,6 +114,11 @@ export const integrationList: any = {
       "https://cdn2.iconfinder.com/data/icons/amazon-aws-stencils/100/Database_copy_Amazon_RDS-512.png",
     label: "Amazon Relational Database Service",
   },
+  s3: {
+    icon:
+      "https://cdn2.iconfinder.com/data/icons/amazon-aws-stencils/100/Database_copy_Amazon_RDS-512.png",
+    label: "Amazon S3 Bucket",
+  },
 };
 
 export const isAlphanumeric = (x: string | null) => {

+ 8 - 0
dashboard/src/shared/types.tsx

@@ -377,6 +377,7 @@ export type InfraKind =
   | "ecr"
   | "eks"
   | "rds"
+  | "s3"
   | "gke"
   | "gcr"
   | "doks"
@@ -482,6 +483,13 @@ export const KindMap: ProviderInfoMap = {
     resource_link: "/databases",
     provider_name: "Relational Database Service (RDS)",
   },
+  s3: {
+    provider: "aws",
+    source: "porter/aws/s3",
+    resource_name: "S3 Bucket",
+    resource_link: "/",
+    provider_name: "AWS S3 Bucket",
+  },
   gcr: {
     provider: "gcp",
     source: "porter/gcp/gcr",

+ 80 - 0
provisioner/server/handlers/state/create_resource.go

@@ -104,6 +104,8 @@ func (c *CreateResourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
 		_, err = createECRRegistry(c.Config, infra, operation, req.Output)
 	case string(types.InfraRDS):
 		_, err = createRDSDatabase(c.Config, infra, operation, req.Output)
+	case string(types.InfraS3):
+		err = createS3Bucket(c.Config, infra, operation, req.Output)
 	case string(types.InfraDOCR):
 		_, err = createDOCRRegistry(c.Config, infra, operation, req.Output)
 	case string(types.InfraGCR):
@@ -217,6 +219,18 @@ func createRDSDatabase(config *config.Config, infra *models.Infra, operation *mo
 	return database, nil
 }
 
+func createS3Bucket(config *config.Config, infra *models.Infra, operation *models.Operation, output map[string]interface{}) error {
+	lastApplied := make(map[string]interface{})
+
+	err := json.Unmarshal(operation.LastApplied, &lastApplied)
+
+	if err != nil {
+		return err
+	}
+
+	return createS3EnvGroup(config, infra, lastApplied, output)
+}
+
 func createCluster(config *config.Config, infra *models.Infra, operation *models.Operation, output map[string]interface{}) (*models.Cluster, error) {
 	// check for infra id being 0 as a safeguard so that all non-provisioned
 	// clusters are not matched by read
@@ -434,3 +448,69 @@ func deleteRDSEnvGroup(config *config.Config, infra *models.Infra, lastApplied m
 
 	return nil
 }
+
+func createS3EnvGroup(config *config.Config, infra *models.Infra, lastApplied map[string]interface{}, output map[string]interface{}) error {
+	cluster, err := config.Repo.Cluster().ReadCluster(infra.ProjectID, infra.ParentClusterID)
+
+	if err != nil {
+		return err
+	}
+
+	ooc := &kubernetes.OutOfClusterConfig{
+		Repo:              config.Repo,
+		DigitalOceanOAuth: config.DOConf,
+		Cluster:           cluster,
+	}
+
+	agent, err := kubernetes.GetAgentOutOfClusterConfig(ooc)
+
+	if err != nil {
+		return fmt.Errorf("failed to get agent: %s", err.Error())
+	}
+
+	// split the instance endpoint on the port
+	_, err = envgroup.CreateEnvGroup(agent, types.ConfigMapInput{
+		Name:      fmt.Sprintf("s3-credentials-%s", lastApplied["bucket_name"].(string)),
+		Namespace: "default",
+		Variables: map[string]string{},
+		SecretVariables: map[string]string{
+			"S3_AWS_ACCESS_KEY_ID": output["s3_aws_access_key_id"].(string),
+			"S3_AWS_SECRET_KEY":    output["s3_aws_secret_key"].(string),
+			"S3_BUCKET_NAME":       output["s3_bucket_name"].(string),
+		},
+	})
+
+	if err != nil {
+		return fmt.Errorf("failed to create S3 env group: %s", err.Error())
+	}
+
+	return nil
+}
+
+func deleteS3EnvGroup(config *config.Config, infra *models.Infra, lastApplied map[string]interface{}) error {
+	cluster, err := config.Repo.Cluster().ReadCluster(infra.ProjectID, infra.ParentClusterID)
+
+	if err != nil {
+		return err
+	}
+
+	ooc := &kubernetes.OutOfClusterConfig{
+		Repo:              config.Repo,
+		DigitalOceanOAuth: config.DOConf,
+		Cluster:           cluster,
+	}
+
+	agent, err := kubernetes.GetAgentOutOfClusterConfig(ooc)
+
+	if err != nil {
+		return fmt.Errorf("failed to get agent: %s", err.Error())
+	}
+
+	err = envgroup.DeleteEnvGroup(agent, fmt.Sprintf("s3-credentials-%s", lastApplied["bucket_name"].(string)), "default")
+
+	if err != nil {
+		return fmt.Errorf("failed to create RDS env group: %s", err.Error())
+	}
+
+	return nil
+}

+ 15 - 0
provisioner/server/handlers/state/delete_resource.go

@@ -1,6 +1,7 @@
 package state
 
 import (
+	"encoding/json"
 	"net/http"
 
 	"github.com/porter-dev/porter/api/server/shared"
@@ -74,6 +75,8 @@ func (c *DeleteResourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request
 		_, err = deleteCluster(c.Config, infra, operation)
 	case types.InfraRDS:
 		_, err = deleteDatabase(c.Config, infra, operation)
+	case types.InfraS3:
+		err = deleteS3Bucket(c.Config, infra, operation)
 	}
 
 	if err != nil {
@@ -131,3 +134,15 @@ func deleteDatabase(config *config.Config, infra *models.Infra, operation *model
 
 	return database, nil
 }
+
+func deleteS3Bucket(config *config.Config, infra *models.Infra, operation *models.Operation) error {
+	lastApplied := make(map[string]interface{})
+
+	err := json.Unmarshal(operation.LastApplied, &lastApplied)
+
+	if err != nil {
+		return err
+	}
+
+	return deleteS3EnvGroup(config, infra, lastApplied)
+}