diff --git a/go.mod b/go.mod index 30411b86..04ec1fd0 100644 --- a/go.mod +++ b/go.mod @@ -66,12 +66,12 @@ require ( require ( github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1 // indirect - github.com/aws/aws-sdk-go-v2 v1.16.14 // indirect + github.com/aws/aws-sdk-go-v2 v1.17.3 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.12.18 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.15 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.21 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.15 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.27 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.21 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.3.22 // indirect github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.6 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.3 // indirect @@ -81,7 +81,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/sso v1.11.21 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.3 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.16.17 // indirect - github.com/aws/smithy-go v1.13.2 // indirect + github.com/aws/smithy-go v1.13.5 // indirect github.com/emicklei/go-restful/v3 v3.8.0 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect github.com/goccy/go-json v0.9.7 // indirect @@ -125,6 +125,7 @@ require ( github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect github.com/aws/aws-sdk-go-v2/config v1.17.5 github.com/aws/aws-sdk-go-v2/service/ec2 v1.51.1 + github.com/aws/aws-sdk-go-v2/service/eks v1.27.0 github.com/aws/aws-sdk-go-v2/service/s3 v1.27.2 github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect diff --git a/go.sum b/go.sum index 09ef6bb7..c5c1f793 100644 --- a/go.sum +++ b/go.sum @@ -192,6 +192,8 @@ github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:o github.com/aws/aws-sdk-go-v2 v1.16.8/go.mod h1:6CpKuLXg2w7If3ABZCl/qZ6rEgwtjZTn4eAf4RcEyuw= github.com/aws/aws-sdk-go-v2 v1.16.14 h1:db6GvO4Z2UqHt5gvT0lr6J5x5P+oQ7bdRzczVaRekMU= github.com/aws/aws-sdk-go-v2 v1.16.14/go.mod h1:s/G+UV29dECbF5rf+RNj1xhlmvoNurGSr+McVSRj59w= +github.com/aws/aws-sdk-go-v2 v1.17.3 h1:shN7NlnVzvDUgPQ+1rLMSxY8OWRNDRYtiqe0p/PgrhY= +github.com/aws/aws-sdk-go-v2 v1.17.3/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3 h1:S/ZBwevQkr7gv5YxONYpGQxlMFFYSRfz3RMcjsC9Qhk= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3/go.mod h1:gNsR5CaXKmQSSzrmGxmwmct/r+ZBfbxorAuXYsj/M5Y= github.com/aws/aws-sdk-go-v2/config v1.17.5 h1:+NS1BWvprx7nHcIk5o32LrZgifs/7Pm1V2nWjQgZ2H0= @@ -203,15 +205,21 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.15/go.mod h1:Oz2/qWINxIgSmoZ github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.15/go.mod h1:pWrr2OoHlT7M/Pd2y4HV3gJyPb3qj5qMmnPkKSNPYK4= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.21 h1:gRIXnmAVNyoRQywdNtpAkgY+f30QNzgF53Q5OobNZZs= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.21/go.mod h1:XsmHMV9c512xgsW01q7H0ut+UQQQpWX8QsFbdLHDwaU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.27 h1:I3cakv2Uy1vNmmhRQmFptYDxOvBnwCdNwyw63N0RaRU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.27/go.mod h1:a1/UpzeyBBerajpnP5nGZa9mGzsBn5cOKxm6NWQsvoI= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.9/go.mod h1:08tUpeSGN33QKSO7fwxXczNfiwCpbj+GxK6XKwqWVv0= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.15 h1:noAhOo2mMDyYhTx99aYPvQw16T3fQ/DiKAv9fzpIKH8= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.15/go.mod h1:kjJ4CyD9M3Wq88GYg3IPfj67Rs0Uvz8aXK7MJ8BvE4I= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.21 h1:5NbbMrIzmUn/TXFqAle6mgrH5m9cOvMLRGL7pnG8tRE= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.21/go.mod h1:+Gxn8jYn5k9ebfHEqlhrMirFjSW0v0C9fI+KN5vk2kE= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.22 h1:nF+E8HfYpOMw6M5oA9efB602VC00IHNQnB5CmFvZPvA= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.22/go.mod h1:tltHVGy977LrSOgRR5aV9+miyno/Gul/uJNPKS7FzP4= github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.6 h1:3L8pcjvgaSOs0zzZcMKzxDSkYKEpwJ2dNVDdxm68jAY= github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.6/go.mod h1:O7Oc4peGZDEKlddivslfYFvAbgzvl/GH3J8j3JIGBXc= github.com/aws/aws-sdk-go-v2/service/ec2 v1.51.1 h1:y88XFO3AJWDVJ3HjcYc+Oo38fB948armdg6ulfphkUM= github.com/aws/aws-sdk-go-v2/service/ec2 v1.51.1/go.mod h1:bKs78Qpk4syfUFXKhA0hIqT3X0sxmvIAPlEHV4qVbP0= +github.com/aws/aws-sdk-go-v2/service/eks v1.27.0 h1:ZXtMY5AgBS6YBtvrlKHSCLuIm5jtLKb/QaUhXH+vCsk= +github.com/aws/aws-sdk-go-v2/service/eks v1.27.0/go.mod h1:H/748RFDDxPmaxe03lhX0ufIQHIO2ctqjTfxuX4N7Vg= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.3 h1:4n4KCtv5SUoT5Er5XV41huuzrCqepxlW3SDI9qHQebc= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.3/go.mod h1:gkb2qADY+OHaGLKNTYxMaQNacfeyQpZ4csDTQMeFmcw= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.10 h1:7LJcuRalaLw+GYQTMGmVUl4opg2HrDZkvn/L3KvIQfw= @@ -232,6 +240,8 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.16.17/go.mod h1:bQujK1n0V1D1Gz5uII1j github.com/aws/smithy-go v1.12.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/aws/smithy-go v1.13.2 h1:TBLKyeJfXTrTXRHmsv4qWt9IQGYyWThLYaJWSahTOGE= github.com/aws/smithy-go v1.13.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8= +github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= diff --git a/pkg/bundle/configuration.go b/pkg/bundle/configuration.go index 79d2d3a3..d71b479e 100644 --- a/pkg/bundle/configuration.go +++ b/pkg/bundle/configuration.go @@ -225,7 +225,7 @@ func bucketName(value string, proj *manifest.ProjectManifest) string { return value } - return fmt.Sprintf("%s-%s-%s", proj.BucketPrefix, proj.Cluster, value) + return fmt.Sprintf("%s-%s-%s", proj.BucketPrefix, utils.TruncString(proj.Cluster, 15), value) } func getEnvVar(repo, itemName string) string { diff --git a/pkg/bundle/configuration_test.go b/pkg/bundle/configuration_test.go index 61aec9c5..4365413f 100644 --- a/pkg/bundle/configuration_test.go +++ b/pkg/bundle/configuration_test.go @@ -113,7 +113,7 @@ func TestConfigureEnvVariables(t *testing.T) { ctx: map[string]interface{}{}, repo: "test", envVars: map[string]string{"PLURAL_TEST_TEST_ITEM": "workspace.yaml"}, - expectedValue: "apiVersion: \"\"\nkind: \"\"\nmetadata: null\nspec:\n cluster: \"\"\n bucket: \"\"\n project: test\n provider: \"\"\n region: \"\"\n owner: null\n network: null\n bucketPrefix: \"\"\n context: {}\n", + expectedValue: "apiVersion: \"\"\nkind: \"\"\nmetadata: null\nspec:\n cluster: \"\"\n bucket: \"\"\n project: test\n provider: \"\"\n region: \"\"\n byok: null\n owner: null\n network: null\n bucketPrefix: \"\"\n context: {}\n", }, } for _, test := range tests { diff --git a/pkg/bundle/surveys.go b/pkg/bundle/surveys.go index c9308e15..78a59263 100644 --- a/pkg/bundle/surveys.go +++ b/pkg/bundle/surveys.go @@ -123,7 +123,7 @@ func bucketSurvey(def string, proj *manifest.ProjectManifest, context *manifest. prompt := "Enter a globally unique object store bucket name " if proj.BucketPrefix != "" { - prompt = fmt.Sprintf("Enter a globally unique bucket name, will be prefixed with %s-%s-", proj.BucketPrefix, proj.Cluster) + prompt = fmt.Sprintf("Enter a globally unique bucket name, will be prefixed with %s-%s-", proj.BucketPrefix, utils.TruncString(proj.Cluster, 15)) } opts := []survey.AskOpt{ diff --git a/pkg/manifest/types.go b/pkg/manifest/types.go index 0b521950..9ea9403a 100644 --- a/pkg/manifest/types.go +++ b/pkg/manifest/types.go @@ -48,12 +48,18 @@ type NetworkConfig struct { PluralDns bool } +type ByokConfig struct { + Enabled bool `yaml:"enabled"` + Type string `yaml:"type"` +} + type ProjectManifest struct { Cluster string Bucket string Project string Provider string Region string + Byok *ByokConfig Owner *Owner Network *NetworkConfig BucketPrefix string `yaml:"bucketPrefix"` diff --git a/pkg/provider/aws.go b/pkg/provider/aws.go index cdba5754..dfaa2da6 100644 --- a/pkg/provider/aws.go +++ b/pkg/provider/aws.go @@ -11,6 +11,7 @@ import ( awsConfig "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/ec2" ec2Types "github.com/aws/aws-sdk-go-v2/service/ec2/types" + "github.com/aws/aws-sdk-go-v2/service/eks" "github.com/aws/aws-sdk-go-v2/service/s3" s3Types "github.com/aws/aws-sdk-go-v2/service/s3/types" v1 "k8s.io/api/core/v1" @@ -23,11 +24,16 @@ import ( plrlErrors "github.com/pluralsh/plural/pkg/utils/errors" ) +const ( + EKS = "eks" +) + type AWSProvider struct { Clus string `survey:"cluster"` project string bucket string Reg string `survey:"region"` + ByokConf *manifest.ByokConfig storageClient *s3.Client writer manifest.Writer goContext *context.Context @@ -60,12 +66,7 @@ var ( } ) -var awsSurvey = []*survey.Question{ - { - Name: "cluster", - Prompt: &survey.Input{Message: "Enter the name of your cluster:"}, - Validate: validCluster, - }, +var initAwsSurvey = []*survey.Question{ { Name: "region", Prompt: &survey.Select{Message: "What region will you deploy to?", Default: "us-east-2", Options: awsRegions}, @@ -73,9 +74,22 @@ var awsSurvey = []*survey.Question{ }, } +var defaultAwsSurvey = []*survey.Question{ + { + Name: "cluster", + Prompt: &survey.Input{Message: "Enter the name of your cluster:"}, + Validate: validClusterName(AWS), + }, +} + func mkAWS(conf config.Config) (provider *AWSProvider, err error) { provider = &AWSProvider{} - if err = survey.Ask(awsSurvey, provider); err != nil { + if err = survey.Ask(initAwsSurvey, provider); err != nil { + return + } + + var createCluster bool + if err = survey.AskOne(&survey.Confirm{Message: "Do you want to create a new cluster?", Default: true}, &createCluster); err != nil { return } @@ -83,11 +97,42 @@ func mkAWS(conf config.Config) (provider *AWSProvider, err error) { provider.goContext = &ctx - client, err := getClient(provider.Reg, *provider.goContext) + s3Client, err := getClient(provider.Reg, *provider.goContext) if err != nil { return } + if !createCluster { + + provider.ByokConf = &manifest.ByokConfig{Enabled: !createCluster, Type: EKS} + + eksClient, err2 := getEksClient(provider.Reg, *provider.goContext) + if err != nil { + return nil, err2 + } + + input := &eks.ListClustersInput{} + clusters, err3 := eksClient.ListClusters(ctx, input) + if err != nil { + return nil, err3 + } + + if err = survey.Ask( + []*survey.Question{ + { + Name: "cluster", + Prompt: &survey.Select{Message: "Select the cluster you want to use:", Options: clusters.Clusters}, + }, + }, provider); err != nil { + return + } + } else { + provider.ByokConf = &manifest.ByokConfig{Enabled: !createCluster} + if err = survey.Ask(defaultAwsSurvey, provider); err != nil { + return + } + } + account, err := GetAwsAccount() if err != nil { err = plrlErrors.ErrorWrap(err, "Failed to get aws account (is your aws cli configured?)") @@ -100,7 +145,7 @@ func mkAWS(conf config.Config) (provider *AWSProvider, err error) { } provider.project = account - provider.storageClient = client + provider.storageClient = s3Client projectManifest := manifest.ProjectManifest{ Cluster: provider.Cluster(), @@ -108,6 +153,7 @@ func mkAWS(conf config.Config) (provider *AWSProvider, err error) { Provider: AWS, Region: provider.Region(), Owner: &manifest.Owner{Email: conf.Email, Endpoint: conf.Endpoint}, + Byok: provider.ByokConf, } provider.writer = projectManifest.Configure() @@ -122,7 +168,19 @@ func awsFromManifest(man *manifest.ProjectManifest) (*AWSProvider, error) { return nil, err } - return &AWSProvider{Clus: man.Cluster, project: man.Project, bucket: man.Bucket, Reg: man.Region, storageClient: client, goContext: &ctx}, nil + return &AWSProvider{Clus: man.Cluster, project: man.Project, bucket: man.Bucket, Reg: man.Region, ByokConf: man.Byok, storageClient: client, goContext: &ctx}, nil +} + +func getEksClient(region string, context context.Context) (*eks.Client, error) { + cfg, err := awsConfig.LoadDefaultConfig(context) + + if err != nil { + return nil, plrlErrors.ErrorWrap(err, "Failed to initialize aws client: ") + } + + cfg.Region = region + + return eks.NewFromConfig(cfg), nil } func getClient(region string, context context.Context) (*s3.Client, error) { @@ -213,6 +271,16 @@ func (aws *AWSProvider) Context() map[string]interface{} { return map[string]interface{}{} } +func (aws *AWSProvider) Byok() map[string]interface{} { + output := make(map[string]interface{}) + if aws.ByokConf != nil { + output["enabled"] = aws.ByokConf.Enabled + output["type"] = aws.ByokConf.Type + } + + return output +} + func (aws *AWSProvider) Preflights() []*Preflight { return nil } diff --git a/pkg/provider/azure.go b/pkg/provider/azure.go index 88223e06..f2e232ef 100644 --- a/pkg/provider/azure.go +++ b/pkg/provider/azure.go @@ -121,7 +121,7 @@ var azureSurvey = []*survey.Question{ { Name: "cluster", Prompt: &survey.Input{Message: "Enter the name of your cluster:"}, - Validate: validCluster, + Validate: validClusterName(AZURE), }, { Name: "storage", @@ -297,6 +297,11 @@ func (az *AzureProvider) Context() map[string]interface{} { return az.ctx } +func (az *AzureProvider) Byok() map[string]interface{} { + output := make(map[string]interface{}) + return output +} + func (az *AzureProvider) Preflights() []*Preflight { return nil } diff --git a/pkg/provider/equinix.go b/pkg/provider/equinix.go index a64e78af..cfb03459 100644 --- a/pkg/provider/equinix.go +++ b/pkg/provider/equinix.go @@ -250,6 +250,11 @@ func (equinix *EQUINIXProvider) Context() map[string]interface{} { return equinix.ctx } +func (equinix *EQUINIXProvider) Byok() map[string]interface{} { + output := make(map[string]interface{}) + return output +} + func (equinix *EQUINIXProvider) Preflights() []*Preflight { return nil } diff --git a/pkg/provider/gcp.go b/pkg/provider/gcp.go index 638289ea..f075e2dc 100644 --- a/pkg/provider/gcp.go +++ b/pkg/provider/gcp.go @@ -79,7 +79,7 @@ func getGCPSurvey() []*survey.Question { { Name: "cluster", Prompt: &survey.Input{Message: "Enter the name of your cluster"}, - Validate: validCluster, + Validate: validClusterName(GCP), }, { Name: "project", @@ -305,6 +305,11 @@ func (gcp *GCPProvider) Context() map[string]interface{} { return gcp.ctx } +func (gcp *GCPProvider) Byok() map[string]interface{} { + output := make(map[string]interface{}) + return output +} + func (gcp *GCPProvider) Decommision(node *v1.Node) error { ctx := context.Background() c, err := compute.NewInstancesRESTClient(ctx) diff --git a/pkg/provider/kind.go b/pkg/provider/kind.go index af9c93a7..ec7c4f1e 100644 --- a/pkg/provider/kind.go +++ b/pkg/provider/kind.go @@ -128,6 +128,11 @@ func (kind *KINDProvider) Context() map[string]interface{} { return kind.ctx } +func (kind *KINDProvider) Byok() map[string]interface{} { + output := make(map[string]interface{}) + return output +} + func (prov *KINDProvider) Decommision(node *v1.Node) error { return nil } diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go index 61a76f0b..17c9ea21 100644 --- a/pkg/provider/provider.go +++ b/pkg/provider/provider.go @@ -21,6 +21,7 @@ type Provider interface { KubeConfig() error CreateBackend(prefix string, version string, ctx map[string]interface{}) (string, error) Context() map[string]interface{} + Byok() map[string]interface{} Decommision(node *v1.Node) error Preflights() []*Preflight Flush() error diff --git a/pkg/provider/validation.go b/pkg/provider/validation.go index 4e069146..ecf15be4 100644 --- a/pkg/provider/validation.go +++ b/pkg/provider/validation.go @@ -9,3 +9,20 @@ var validCluster = survey.ComposeValidators( utils.ValidateAlphaNumeric, survey.MaxLength(15), ) + +func validClusterName(provider string) survey.Validator { + var length int + length = 15 + switch provider { + case GCP: + length = 40 + case AWS: + length = 100 + case AZURE: + length = 63 + } + return survey.ComposeValidators( + utils.ValidateAlphaNumeric, + survey.MaxLength(length), + ) +} diff --git a/pkg/scaffold/helm.go b/pkg/scaffold/helm.go index a1bac799..3a5af9cf 100644 --- a/pkg/scaffold/helm.go +++ b/pkg/scaffold/helm.go @@ -103,6 +103,7 @@ func Notes(installation *api.Installation) error { "Provider": prov.Name(), "Context": prov.Context(), "Applications": BuildApplications(repoRoot), + "BYOK": prov.Byok(), } if context.Globals != nil { diff --git a/pkg/scaffold/terraform.go b/pkg/scaffold/terraform.go index a24a4a4b..f91015ae 100644 --- a/pkg/scaffold/terraform.go +++ b/pkg/scaffold/terraform.go @@ -123,7 +123,9 @@ func (scaffold *Scaffold) handleTerraform(wk *wkspace.Workspace) error { "Region": wk.Provider.Region(), "Context": wk.Provider.Context(), "Applications": apps, + "BYOK": wk.Provider.Byok(), } + if err := tmpl.Execute(&buf, values); err != nil { return err } diff --git a/pkg/utils/string.go b/pkg/utils/string.go index 8d5a1728..20efe81b 100644 --- a/pkg/utils/string.go +++ b/pkg/utils/string.go @@ -14,3 +14,13 @@ func Pluralize(one, many string, count int) string { func ToString(val interface{}) string { return fmt.Sprintf("%v", val) } + +func TruncString(s string, c int) string { + if c < 0 && len(s)+c > 0 { + return s[len(s)+c:] + } + if c >= 0 && len(s) > c { + return s[:c] + } + return s +}