From bdccf8d176eed28d309aa83ac239760ffbb684a9 Mon Sep 17 00:00:00 2001 From: hunterkepley Date: Thu, 5 Dec 2024 09:50:50 -0500 Subject: [PATCH] OCM-12364 | feat: create/cluster validation for hcpsharedvpc flags --- cmd/create/cluster/cmd.go | 35 +++++++++++++++- cmd/create/cluster/validation.go | 38 ++++++++++++++++++ cmd/create/cluster/validation_test.go | 57 +++++++++++++++++++++++++++ 3 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 cmd/create/cluster/validation.go create mode 100644 cmd/create/cluster/validation_test.go diff --git a/cmd/create/cluster/cmd.go b/cmd/create/cluster/cmd.go index 8ac1eb819..bd8393f4a 100644 --- a/cmd/create/cluster/cmd.go +++ b/cmd/create/cluster/cmd.go @@ -2332,7 +2332,39 @@ func run(cmd *cobra.Command, _ []string) { isSharedVPC = true } - if len(subnetIDs) == 0 && isSharedVPC { + // validate flags for hcp shared vpc + isHcpSharedVpc := false + route53RoleArn := sharedVPCRoleARN // TODO: Change when fully deprecating old flag name + vpcEndpointRoleArn := strings.Trim(args.vpcEndpointRoleArn, " \t") + hcpInternalCommunicationHostedZoneId := strings.Trim(args.hcpInternalCommunicationHostedZoneId, " \t") + ingressPrivateHostedZoneId := privateHostedZoneID // TODO: Change when fully deprecating old flag name + + anyHcpSharedVpcFlagsUsed := route53RoleArn != "" || vpcEndpointRoleArn != "" || + hcpInternalCommunicationHostedZoneId != "" || ingressPrivateHostedZoneId != "" + + if anyHcpSharedVpcFlagsUsed { + if isHostedCP { + isHcpSharedVpc = true + err = validateHcpSharedVpcArgs(route53RoleArn, vpcEndpointRoleArn, ingressPrivateHostedZoneId, + hcpInternalCommunicationHostedZoneId) + if err != nil { + r.Reporter.Errorf("Error when validating flags: %v", err) + os.Exit(1) + } + } else { + if vpcEndpointRoleArn != "" { + r.Reporter.Errorf(hcpSharedVpcFlagOnlyErrorMsg, + vpcEndpointRoleArnFlag) + os.Exit(1) + } else if hcpInternalCommunicationHostedZoneId != "" { + r.Reporter.Errorf(hcpSharedVpcFlagOnlyErrorMsg, + hcpInternalCommunicationHostedZoneIdFlag) + os.Exit(1) + } + } + } + + if len(subnetIDs) == 0 && (isSharedVPC || isHcpSharedVpc) { r.Reporter.Errorf("Installing a cluster into a shared VPC is only supported for BYO VPC clusters") os.Exit(1) } @@ -2347,6 +2379,7 @@ func run(cmd *cobra.Command, _ []string) { } isSharedVPC = true + if privateHostedZoneID == "" || sharedVPCRoleARN == "" || baseDomain == "" { if !interactive.Enabled() { interactive.Enable() diff --git a/cmd/create/cluster/validation.go b/cmd/create/cluster/validation.go new file mode 100644 index 000000000..4adde05ce --- /dev/null +++ b/cmd/create/cluster/validation.go @@ -0,0 +1,38 @@ +package cluster + +import ( + "fmt" + + "github.com/aws/aws-sdk-go-v2/aws/arn" +) + +const ( + hcpSharedVpcFlagOnlyErrorMsg = "setting the '%s' flag is only supported when creating a Hosted Control Plane " + + "cluster" + + hcpSharedVpcFlagNotFilledErrorMsg = "must supply '%s' flag when creating a Hosted Control Plane shared VPC cluster" + + isNotValidArnErrorMsg = "ARN supplied with flag '%s' is not a valid ARN format" +) + +func validateHcpSharedVpcArgs(route53RoleArn string, vpcEndpointRoleArn string, + ingressPrivateHostedZoneId string, hcpInternalCommunicationHostedZoneId string) error { + + if route53RoleArn == "" { + return fmt.Errorf(hcpSharedVpcFlagNotFilledErrorMsg, route53RoleArnFlag) + } else if !arn.IsARN(route53RoleArn) { + return fmt.Errorf(isNotValidArnErrorMsg, route53RoleArnFlag) + } + if vpcEndpointRoleArn == "" { + return fmt.Errorf(hcpSharedVpcFlagNotFilledErrorMsg, vpcEndpointRoleArnFlag) + } else if !arn.IsARN(vpcEndpointRoleArn) { + return fmt.Errorf(isNotValidArnErrorMsg, vpcEndpointRoleArnFlag) + } + if ingressPrivateHostedZoneId == "" { + return fmt.Errorf(hcpSharedVpcFlagNotFilledErrorMsg, ingressPrivateHostedZoneIdFlag) + } + if hcpInternalCommunicationHostedZoneId == "" { + return fmt.Errorf(hcpSharedVpcFlagNotFilledErrorMsg, hcpInternalCommunicationHostedZoneIdFlag) + } + return nil +} diff --git a/cmd/create/cluster/validation_test.go b/cmd/create/cluster/validation_test.go new file mode 100644 index 000000000..023c9127f --- /dev/null +++ b/cmd/create/cluster/validation_test.go @@ -0,0 +1,57 @@ +package cluster + +import ( + "fmt" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("Test validation functions", func() { + + validTestArn := "arn:aws:iam::123456789012:role/test" + invalidTestArn := "123arn:aws?" + + Context("Validation of HCP shared VPC", func() { + When("isHostedCp", func() { + It("OK: Passes validation (all flags filled out and correct format", func() { + err := validateHcpSharedVpcArgs(validTestArn, validTestArn, "123", "123") + Expect(err).ToNot(HaveOccurred()) + }) + It("KO: Invalid Route53 ARN", func() { + err := validateHcpSharedVpcArgs(invalidTestArn, validTestArn, "123", "123") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring(fmt.Sprintf(isNotValidArnErrorMsg, route53RoleArnFlag))) + }) + It("KO: invalid VPC Endpoint ARN", func() { + err := validateHcpSharedVpcArgs(validTestArn, invalidTestArn, "123", "123") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring(fmt.Sprintf(isNotValidArnErrorMsg, vpcEndpointRoleArnFlag))) + }) + It("KO: Route53 ARN flag not populated", func() { + err := validateHcpSharedVpcArgs("", validTestArn, "123", "123") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring(fmt.Sprintf(hcpSharedVpcFlagNotFilledErrorMsg, + route53RoleArnFlag))) + }) + It("KO: VPC Endpoint ARN flag not populated", func() { + err := validateHcpSharedVpcArgs(validTestArn, "", "123", "123") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring(fmt.Sprintf(hcpSharedVpcFlagNotFilledErrorMsg, + vpcEndpointRoleArnFlag))) + }) + It("KO: Ingress Private Hosted Zone ID flag not populated", func() { + err := validateHcpSharedVpcArgs(validTestArn, validTestArn, "", "123") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring(fmt.Sprintf(hcpSharedVpcFlagNotFilledErrorMsg, + ingressPrivateHostedZoneIdFlag))) + }) + It("KO: HCP Internal Communication Hosted Zone ID flag not populated", func() { + err := validateHcpSharedVpcArgs(validTestArn, validTestArn, "123", "") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring(fmt.Sprintf(hcpSharedVpcFlagNotFilledErrorMsg, + hcpInternalCommunicationHostedZoneIdFlag))) + }) + }) + }) +})