-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AWS BYOK #312
base: main
Are you sure you want to change the base?
AWS BYOK #312
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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,34 +66,73 @@ 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}, | ||
Validate: survey.Required, | ||
}, | ||
} | ||
|
||
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 | ||
} | ||
|
||
ctx := context.Background() | ||
|
||
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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should factor this into a separate method probably to keep this one less sprawling |
||
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,14 +145,15 @@ func mkAWS(conf config.Config) (provider *AWSProvider, err error) { | |
} | ||
|
||
provider.project = account | ||
provider.storageClient = client | ||
provider.storageClient = s3Client | ||
|
||
projectManifest := manifest.ProjectManifest{ | ||
Cluster: provider.Cluster(), | ||
Project: provider.Project(), | ||
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{} { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is there a reason we can't just use the struct as the return val here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is what I was trying to do first which also didn't need this function, but for some reason only the values were being returned during templating. But this is indeed something that I think should be cleaned up. |
||
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 | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also add to this note that if they don't create a cluster, they should only chose a newly created, fresh cluster
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can add the note, but I'm not sure how strictly necessary this is since clashing applications can be disabled. I didn't add it in the artifact (yet), but I think the only one left is cert-manager. External DNS is limited to the subdomain set in the workspace so might not clash, but potentially could so we can add a way to disable that as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking more if you have the zalando postgres operator or nginx ingress controller already installed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same w/ cert manager tbh