From 26633b5241356e43a6347c5de7856cec40ee54ad Mon Sep 17 00:00:00 2001 From: esierra-stratio <102975650+esierra-stratio@users.noreply.github.com> Date: Thu, 19 Oct 2023 13:46:18 +0200 Subject: [PATCH] chore: validate region exists (#337) * chore: validate region * rename func validate aws * change name function --- pkg/cluster/internal/validate/aws.go | 43 ++++++++++++++++++++++---- pkg/cluster/internal/validate/azure.go | 34 ++++++++++++++++++++ pkg/cluster/internal/validate/gcp.go | 41 ++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 6 deletions(-) diff --git a/pkg/cluster/internal/validate/aws.go b/pkg/cluster/internal/validate/aws.go index dace24d601..ad126da79a 100644 --- a/pkg/cluster/internal/validate/aws.go +++ b/pkg/cluster/internal/validate/aws.go @@ -52,7 +52,15 @@ func validateAWS(spec commons.Spec, providerSecrets map[string]string) error { return err } - azs, err := getAwsAzs(ctx, cfg, spec.Region) + regions, err := getAWSRegions(cfg) + if err != nil { + return err + } + if !commons.Contains(regions, spec.Region) { + return errors.New("spec.region: " + spec.Region + " region does not exist") + } + + azs, err := getAWSAzs(ctx, cfg, spec.Region) if err != nil { return err } @@ -152,14 +160,14 @@ func validateAWSNetwork(ctx context.Context, cfg aws.Config, spec commons.Spec) } } if spec.Networks.VPCID != "" { - vpcs, _ := getAwsVPCs(cfg) + vpcs, _ := getAWSVPCs(cfg) if len(vpcs) > 0 && !commons.Contains(vpcs, spec.Networks.VPCID) { return errors.New("\"vpc_id\": " + spec.Networks.VPCID + " does not exist") } if len(spec.Networks.Subnets) == 0 { return errors.New("\"subnets\": are required when \"vpc_id\" is set") } else { - subnets, _ := getAwsSubnets(spec.Networks.VPCID, cfg) + subnets, _ := getAWSSubnets(spec.Networks.VPCID, cfg) if len(subnets) > 0 { for _, subnet := range spec.Networks.Subnets { if !commons.Contains(subnets, subnet.SubnetId) { @@ -218,7 +226,30 @@ func validateAWSPodsNetwork(podsNetwork string) error { return nil } -func getAwsVPCs(config aws.Config) ([]string, error) { +func getAWSRegions(config aws.Config) ([]string, error) { + regions := []string{} + + // Use a default region to authenticate + config.Region = *aws.String("eu-west-1") + + client := ec2.NewFromConfig(config) + + // Describe regions + describeRegionsOpts := &ec2.DescribeRegionsInput{} + output, err := client.DescribeRegions(context.Background(), describeRegionsOpts) + if err != nil { + return nil, err + } + + // Extract region names + for _, region := range output.Regions { + regions = append(regions, *region.RegionName) + } + + return regions, nil +} + +func getAWSVPCs(config aws.Config) ([]string, error) { vpcs := []string{} client := ec2.NewFromConfig(config) @@ -233,7 +264,7 @@ func getAwsVPCs(config aws.Config) ([]string, error) { return vpcs, nil } -func getAwsSubnets(vpcId string, config aws.Config) ([]string, error) { +func getAWSSubnets(vpcId string, config aws.Config) ([]string, error) { subnets := []string{} client := ec2.NewFromConfig(config) @@ -374,7 +405,7 @@ func validateAWSAZs(ctx context.Context, cfg aws.Config, spec commons.Spec) erro return nil } -func getAwsAzs(ctx context.Context, cfg aws.Config, region string) ([]string, error) { +func getAWSAzs(ctx context.Context, cfg aws.Config, region string) ([]string, error) { var azs []string svc := ec2.NewFromConfig(cfg) result, err := svc.DescribeAvailabilityZones(ctx, &ec2.DescribeAvailabilityZonesInput{}) diff --git a/pkg/cluster/internal/validate/azure.go b/pkg/cluster/internal/validate/azure.go index 8c1a240f2c..831b68ea79 100644 --- a/pkg/cluster/internal/validate/azure.go +++ b/pkg/cluster/internal/validate/azure.go @@ -53,6 +53,16 @@ func validateAzure(spec commons.Spec, providerSecrets map[string]string, cluster if err != nil { return err } + + regions, err := getAzureRegions(creds, providerSecrets["SubscriptionID"]) + fmt.Println(regions) + if err != nil { + return err + } + if !commons.Contains(regions, spec.Region) { + return errors.New("spec.region: " + spec.Region + " region does not exist") + } + azs, err := getAzureAzs(creds, providerSecrets["SubscriptionID"], spec.Region) if err != nil { return err @@ -369,6 +379,30 @@ func getAzureAzs(creds *azidentity.ClientSecretCredential, subscription string, return azs, nil } +func getAzureRegions(creds *azidentity.ClientSecretCredential, subscription string) ([]string, error) { + regions := []string{} + + ctx := context.Background() + clientFactory, err := armsubscriptions.NewClientFactory(creds, nil) + if err != nil { + return []string{}, err + } + + pager := clientFactory.NewClient().NewListLocationsPager(subscription, &armsubscriptions.ClientListLocationsOptions{IncludeExtendedLocations: nil}) + for pager.More() { + page, err := pager.NextPage(ctx) + if err != nil { + return []string{}, err + } + for _, v := range page.Value { + if !commons.Contains(regions, *v.Name) { + regions = append(regions, *v.Name) + } + } + } + return regions, nil +} + func getAzureVpcs(creds *azidentity.ClientSecretCredential, subscription string, region string, resourceGroup string) ([]string, error) { ctx := context.Background() vpcs := []string{} diff --git a/pkg/cluster/internal/validate/gcp.go b/pkg/cluster/internal/validate/gcp.go index 4fa1634ae8..8ae38db3f9 100644 --- a/pkg/cluster/internal/validate/gcp.go +++ b/pkg/cluster/internal/validate/gcp.go @@ -43,6 +43,15 @@ func validateGCP(spec commons.Spec, providerSecrets map[string]string) error { var isGKEVersion = regexp.MustCompile(`^v\d.\d{2}.\d{1,2}-gke.\d{3,4}$`).MatchString credentialsJson := getGCPCreds(providerSecrets) + + regions, err := getGCPRegions(credentialsJson) + if err != nil { + return err + } + if !commons.Contains(regions, spec.Region) { + return errors.New("spec.region: " + spec.Region + " region does not exist") + } + azs, err := getGoogleAZs(credentialsJson, spec.Region) if err != nil { return err @@ -215,6 +224,38 @@ func validateGCPNetwork(network commons.Networks, credentialsJson string, region return nil } +func getGCPRegions(credentialsJson string) ([]string, error) { + var regions_names []string + var ctx = context.Background() + + gcpCreds := map[string]string{} + err := json.Unmarshal([]byte(credentialsJson), &gcpCreds) + if err != nil { + return []string{}, err + } + + cfg := option.WithCredentialsJSON([]byte(credentialsJson)) + computeService, err := compute.NewService(ctx, cfg) + + if err != nil { + return []string{}, err + } + + regions, err := computeService.Regions.List(string(gcpCreds["project_id"])).Do() + if err != nil { + return []string{}, err + } + + for _, region := range regions.Items { + if !commons.Contains(regions_names, region.Name) { + regions_names = append(regions_names, region.Name) + } + } + + return regions_names, nil + +} + func getGoogleVPCs(credentialsJson string) ([]string, error) { var network_names []string var ctx = context.Background()