diff --git a/api/powervs/v1beta2/types.go b/api/powervs/v1beta2/types.go index 112165912..f59adf71c 100644 --- a/api/powervs/v1beta2/types.go +++ b/api/powervs/v1beta2/types.go @@ -285,14 +285,20 @@ var ( ) const ( - // VPCSecurityGroupRuleProtocolAllType is a string representation of the 'SecurityGroupRuleSecurityGroupRuleProtocolAll' type. - VPCSecurityGroupRuleProtocolAllType = "*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll" + // VPCSecurityGroupRuleProtocolAnyType is a string representation of the 'SecurityGroupRuleProtocolAny' type. + VPCSecurityGroupRuleProtocolAnyType = "*vpcv1.SecurityGroupRuleProtocolAny" + + // VPCSecurityGroupRuleProtocolIcmptcpudpType is a string representation of the 'SecurityGroupRuleProtocolIcmptcpudp' type. + VPCSecurityGroupRuleProtocolIcmptcpudpType = "*vpcv1.SecurityGroupRuleProtocolIcmptcpudp" // VPCSecurityGroupRuleProtocolIcmpType is a string representation of the 'SecurityGroupRuleSecurityGroupRuleProtocolIcmp' type. VPCSecurityGroupRuleProtocolIcmpType = "*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp" // VPCSecurityGroupRuleProtocolTcpudpType is a string representation of the 'SecurityGroupRuleSecurityGroupRuleProtocolTcpudp' type. VPCSecurityGroupRuleProtocolTcpudpType = "*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp" + + // VPCSecurityGroupRuleProtocolIndividualType is a string representation of the 'SecurityGroupRuleProtocolIndividual' type. + VPCSecurityGroupRuleProtocolIndividualType = "*vpcv1.SecurityGroupRuleProtocolIndividual" ) // VPCSecurityGroupRuleAction represents the actions for a Security Group Rule. @@ -318,12 +324,14 @@ const ( ) // VPCSecurityGroupRuleProtocol represents the protocols for a Security Group Rule. -// +kubebuilder:validation:Enum=all;icmp;tcp;udp +// +kubebuilder:validation:Pattern=`^(any|icmp_tcp_udp|icmp|tcp|udp|ah|esp|gre|ip_in_ip|l2tp|rsvp|sctp|vrrp|number_(?:0|2|3|5|[7-9]|1[0-6]|1[8-9]|[2-3][0-9]|4[0-5]|4[89]|5[2-9]|[6-9][0-9]|10[0-9]|11[0-1]|11[3-4]|11[6-9]|12[0-9]|13[0-1]|13[3-9]|1[4-9][0-9]|2[0-4][0-9]|25[0-5]))$` type VPCSecurityGroupRuleProtocol string const ( - // VPCSecurityGroupRuleProtocolAll defines the Rule is for all network protocols. - VPCSecurityGroupRuleProtocolAll VPCSecurityGroupRuleProtocol = vpcv1.NetworkACLRuleProtocolAllConst + // VPCSecurityGroupRuleProtocolAny defines the Rule is for any network protocols. + VPCSecurityGroupRuleProtocolAny VPCSecurityGroupRuleProtocol = vpcv1.NetworkACLRuleProtocolAnyConst + // VPCSecurityGroupRuleProtocolIcmpTCPUDP defines the Rule is for ICMP, TCP and UDP protocols. + VPCSecurityGroupRuleProtocolIcmpTCPUDP VPCSecurityGroupRuleProtocol = vpcv1.NetworkACLRuleProtocolIcmpTCPUDPConst // VPCSecurityGroupRuleProtocolIcmp defiens the Rule is for ICMP network protocol. VPCSecurityGroupRuleProtocolIcmp VPCSecurityGroupRuleProtocol = vpcv1.NetworkACLRuleProtocolIcmpConst // VPCSecurityGroupRuleProtocolTCP defines the Rule is for TCP network protocol. @@ -446,8 +454,9 @@ type VPCSecurityGroupRuleRemote struct { // VPCSecurityGroupRulePrototype defines a VPC Security Group Rule's traffic specifics for a series of remotes (destinations or sources). // +kubebuilder:validation:XValidation:rule="self.protocol != 'icmp' ? (!has(self.icmpCode) && !has(self.icmpType)) : true",message="icmpCode and icmpType are only supported for VPCSecurityGroupRuleProtocolIcmp protocol" -// +kubebuilder:validation:XValidation:rule="self.protocol == 'all' ? !has(self.portRange) : true",message="portRange is not valid for VPCSecurityGroupRuleProtocolAll protocol" // +kubebuilder:validation:XValidation:rule="self.protocol == 'icmp' ? !has(self.portRange) : true",message="portRange is not valid for VPCSecurityGroupRuleProtocolIcmp protocol" +// +kubebuilder:validation:XValidation:rule="(self.protocol != 'tcp' && self.protocol != 'udp') ? !has(self.portRange) : true",message="portRange is not valid for protocol" +// +kubebuilder:validation:XValidation:rule="self.protocol == 'icmp_tcp_udp' ? !has(self.portRange) : true",message="portRange is not valid for VPCSecurityGroupRuleProtocolIcmpTCPUDP protocol" type VPCSecurityGroupRulePrototype struct { // icmpCode is the ICMP code for the Rule. // Only used when Protocol is VPCSecurityGroupRuleProtocolIcmp. diff --git a/api/powervs/v1beta3/types.go b/api/powervs/v1beta3/types.go index 5bd18d01f..379a5b68e 100644 --- a/api/powervs/v1beta3/types.go +++ b/api/powervs/v1beta3/types.go @@ -285,14 +285,20 @@ var ( ) const ( - // VPCSecurityGroupRuleProtocolAllType is a string representation of the 'SecurityGroupRuleSecurityGroupRuleProtocolAll' type. - VPCSecurityGroupRuleProtocolAllType = "*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll" + // VPCSecurityGroupRuleProtocolAnyType is a string representation of the 'SecurityGroupRuleProtocolAny' type. + VPCSecurityGroupRuleProtocolAnyType = "*vpcv1.SecurityGroupRuleProtocolAny" + + // VPCSecurityGroupRuleProtocolIcmptcpudpType is a string representation of the 'SecurityGroupRuleProtocolIcmptcpudp' type. + VPCSecurityGroupRuleProtocolIcmptcpudpType = "*vpcv1.SecurityGroupRuleProtocolIcmptcpudp" // VPCSecurityGroupRuleProtocolIcmpType is a string representation of the 'SecurityGroupRuleSecurityGroupRuleProtocolIcmp' type. VPCSecurityGroupRuleProtocolIcmpType = "*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp" // VPCSecurityGroupRuleProtocolTcpudpType is a string representation of the 'SecurityGroupRuleSecurityGroupRuleProtocolTcpudp' type. VPCSecurityGroupRuleProtocolTcpudpType = "*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp" + + // VPCSecurityGroupRuleProtocolIndividualType is a string representation of the 'SecurityGroupRuleProtocolIndividual' type. + VPCSecurityGroupRuleProtocolIndividualType = "*vpcv1.SecurityGroupRuleProtocolIndividual" ) // VPCSecurityGroupRuleAction represents the actions for a Security Group Rule. @@ -318,12 +324,14 @@ const ( ) // VPCSecurityGroupRuleProtocol represents the protocols for a Security Group Rule. -// +kubebuilder:validation:Enum=all;icmp;tcp;udp +// +kubebuilder:validation:Pattern=`^(any|icmp_tcp_udp|icmp|tcp|udp|ah|esp|gre|ip_in_ip|l2tp|rsvp|sctp|vrrp|number_(?:0|2|3|5|[7-9]|1[0-6]|1[8-9]|[2-3][0-9]|4[0-5]|4[89]|5[2-9]|[6-9][0-9]|10[0-9]|11[0-1]|11[3-4]|11[6-9]|12[0-9]|13[0-1]|13[3-9]|1[4-9][0-9]|2[0-4][0-9]|25[0-5]))$` type VPCSecurityGroupRuleProtocol string const ( - // VPCSecurityGroupRuleProtocolAll defines the Rule is for all network protocols. - VPCSecurityGroupRuleProtocolAll VPCSecurityGroupRuleProtocol = vpcv1.NetworkACLRuleProtocolAllConst + // VPCSecurityGroupRuleProtocolAny defines the Rule is for any network protocols. + VPCSecurityGroupRuleProtocolAny VPCSecurityGroupRuleProtocol = vpcv1.NetworkACLRuleProtocolAnyConst + // VPCSecurityGroupRuleProtocolIcmpTCPUDP defines the Rule is for ICMP, TCP and UDP protocols. + VPCSecurityGroupRuleProtocolIcmpTCPUDP VPCSecurityGroupRuleProtocol = vpcv1.NetworkACLRuleProtocolIcmpTCPUDPConst // VPCSecurityGroupRuleProtocolIcmp defiens the Rule is for ICMP network protocol. VPCSecurityGroupRuleProtocolIcmp VPCSecurityGroupRuleProtocol = vpcv1.NetworkACLRuleProtocolIcmpConst // VPCSecurityGroupRuleProtocolTCP defines the Rule is for TCP network protocol. @@ -446,8 +454,9 @@ type VPCSecurityGroupRuleRemote struct { // VPCSecurityGroupRulePrototype defines a VPC Security Group Rule's traffic specifics for a series of remotes (destinations or sources). // +kubebuilder:validation:XValidation:rule="self.protocol != 'icmp' ? (!has(self.icmpCode) && !has(self.icmpType)) : true",message="icmpCode and icmpType are only supported for VPCSecurityGroupRuleProtocolIcmp protocol" -// +kubebuilder:validation:XValidation:rule="self.protocol == 'all' ? !has(self.portRange) : true",message="portRange is not valid for VPCSecurityGroupRuleProtocolAll protocol" // +kubebuilder:validation:XValidation:rule="self.protocol == 'icmp' ? !has(self.portRange) : true",message="portRange is not valid for VPCSecurityGroupRuleProtocolIcmp protocol" +// +kubebuilder:validation:XValidation:rule="(self.protocol != 'tcp' && self.protocol != 'udp') ? !has(self.portRange) : true",message="portRange is not valid for protocol" +// +kubebuilder:validation:XValidation:rule="self.protocol == 'icmp_tcp_udp' ? !has(self.portRange) : true",message="portRange is not valid for VPCSecurityGroupRuleProtocolIcmpTCPUDP protocol" type VPCSecurityGroupRulePrototype struct { // icmpCode is the ICMP code for the Rule. // Only used when Protocol is VPCSecurityGroupRuleProtocolIcmp. diff --git a/api/vpc/v1beta2/types.go b/api/vpc/v1beta2/types.go index d43dc17fd..d077c6a03 100644 --- a/api/vpc/v1beta2/types.go +++ b/api/vpc/v1beta2/types.go @@ -164,14 +164,20 @@ var ( ) const ( - // VPCSecurityGroupRuleProtocolAllType is a string representation of the 'SecurityGroupRuleSecurityGroupRuleProtocolAll' type. - VPCSecurityGroupRuleProtocolAllType = "*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll" + // VPCSecurityGroupRuleProtocolAnyType is a string representation of the 'SecurityGroupRuleProtocolAny' type. + VPCSecurityGroupRuleProtocolAnyType = "*vpcv1.SecurityGroupRuleProtocolAny" + + // VPCSecurityGroupRuleProtocolIcmptcpudpType is a string representation of the 'SecurityGroupRuleProtocolIcmptcpudp' type. + VPCSecurityGroupRuleProtocolIcmptcpudpType = "*vpcv1.SecurityGroupRuleProtocolIcmptcpudp" // VPCSecurityGroupRuleProtocolIcmpType is a string representation of the 'SecurityGroupRuleSecurityGroupRuleProtocolIcmp' type. VPCSecurityGroupRuleProtocolIcmpType = "*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp" // VPCSecurityGroupRuleProtocolTcpudpType is a string representation of the 'SecurityGroupRuleSecurityGroupRuleProtocolTcpudp' type. VPCSecurityGroupRuleProtocolTcpudpType = "*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp" + + // VPCSecurityGroupRuleProtocolIndividualType is a string representation of the 'SecurityGroupRuleProtocolIndividual' type. + VPCSecurityGroupRuleProtocolIndividualType = "*vpcv1.SecurityGroupRuleProtocolIndividual" ) // VPCSecurityGroupRuleAction represents the actions for a Security Group Rule. @@ -197,12 +203,14 @@ const ( ) // VPCSecurityGroupRuleProtocol represents the protocols for a Security Group Rule. -// +kubebuilder:validation:Enum=all;icmp;tcp;udp +// +kubebuilder:validation:Pattern=`^(any|icmp_tcp_udp|icmp|tcp|udp|ah|esp|gre|ip_in_ip|l2tp|rsvp|sctp|vrrp|number_(?:0|2|3|5|[7-9]|1[0-6]|1[8-9]|[2-3][0-9]|4[0-5]|4[89]|5[2-9]|[6-9][0-9]|10[0-9]|11[0-1]|11[3-4]|11[6-9]|12[0-9]|13[0-1]|13[3-9]|1[4-9][0-9]|2[0-4][0-9]|25[0-5]))$` type VPCSecurityGroupRuleProtocol string const ( - // VPCSecurityGroupRuleProtocolAll defines the Rule is for all network protocols. - VPCSecurityGroupRuleProtocolAll VPCSecurityGroupRuleProtocol = vpcv1.NetworkACLRuleProtocolAllConst + // VPCSecurityGroupRuleProtocolAny defines the Rule is for any network protocols. + VPCSecurityGroupRuleProtocolAny VPCSecurityGroupRuleProtocol = vpcv1.NetworkACLRuleProtocolAnyConst + // VPCSecurityGroupRuleProtocolIcmpTCPUDP defines the Rule is for ICMP, TCP and UDP protocols. + VPCSecurityGroupRuleProtocolIcmpTCPUDP VPCSecurityGroupRuleProtocol = vpcv1.NetworkACLRuleProtocolIcmpTCPUDPConst // VPCSecurityGroupRuleProtocolIcmp defiens the Rule is for ICMP network protocol. VPCSecurityGroupRuleProtocolIcmp VPCSecurityGroupRuleProtocol = vpcv1.NetworkACLRuleProtocolIcmpConst // VPCSecurityGroupRuleProtocolTCP defines the Rule is for TCP network protocol. @@ -398,8 +406,9 @@ type VPCSecurityGroupRuleRemote struct { // VPCSecurityGroupRulePrototype defines a VPC Security Group Rule's traffic specifics for a series of remotes (destinations or sources). // +kubebuilder:validation:XValidation:rule="self.protocol != 'icmp' ? (!has(self.icmpCode) && !has(self.icmpType)) : true",message="icmpCode and icmpType are only supported for VPCSecurityGroupRuleProtocolIcmp protocol" -// +kubebuilder:validation:XValidation:rule="self.protocol == 'all' ? !has(self.portRange) : true",message="portRange is not valid for VPCSecurityGroupRuleProtocolAll protocol" // +kubebuilder:validation:XValidation:rule="self.protocol == 'icmp' ? !has(self.portRange) : true",message="portRange is not valid for VPCSecurityGroupRuleProtocolIcmp protocol" +// +kubebuilder:validation:XValidation:rule="(self.protocol != 'tcp' && self.protocol != 'udp') ? !has(self.portRange) : true",message="portRange is not valid for protocol" +// +kubebuilder:validation:XValidation:rule="self.protocol == 'icmp_tcp_udp' ? !has(self.portRange) : true",message="portRange is not valid for VPCSecurityGroupRuleProtocolIcmpTCPUDP protocol" type VPCSecurityGroupRulePrototype struct { // icmpCode is the ICMP code for the Rule. // Only used when Protocol is VPCSecurityGroupRuleProtocolIcmp. diff --git a/cloud/scope/powervs/powervs_cluster.go b/cloud/scope/powervs/powervs_cluster.go index a2cbd7c82..2e35d1365 100644 --- a/cloud/scope/powervs/powervs_cluster.go +++ b/cloud/scope/powervs/powervs_cluster.go @@ -1462,15 +1462,21 @@ func (s *ClusterScope) createVPCSecurityGroupRule(ctx context.Context, securityG } switch reflect.TypeOf(ruleIntf).String() { - case "*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll": - rule := ruleIntf.(*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll) + case infrav1.VPCSecurityGroupRuleProtocolAnyType: + rule := ruleIntf.(*vpcv1.SecurityGroupRuleProtocolAny) ruleID = rule.ID - case "*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp": + case infrav1.VPCSecurityGroupRuleProtocolIcmptcpudpType: + rule := ruleIntf.(*vpcv1.SecurityGroupRuleProtocolIcmptcpudp) + ruleID = rule.ID + case infrav1.VPCSecurityGroupRuleProtocolTcpudpType: rule := ruleIntf.(*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp) ruleID = rule.ID - case "*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp": + case infrav1.VPCSecurityGroupRuleProtocolIcmpType: rule := ruleIntf.(*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp) ruleID = rule.ID + case infrav1.VPCSecurityGroupRuleProtocolIndividualType: + rule := ruleIntf.(*vpcv1.SecurityGroupRuleProtocolIndividual) + ruleID = rule.ID } log.Info("Created VPC security group rule", "ruleID", *ruleID) return ruleID, nil @@ -1600,7 +1606,7 @@ func (s *ClusterScope) validateVPCSecurityGroupRuleRemote(originalSGRemote *vpcv } // validateSecurityGroupRule compares a specific security group's rule with the spec and existing security group's rule. -func (s *ClusterScope) validateSecurityGroupRule(originalSecurityGroupRules []vpcv1.SecurityGroupRuleIntf, direction infrav1.VPCSecurityGroupRuleDirection, rule *infrav1.VPCSecurityGroupRulePrototype, remote infrav1.VPCSecurityGroupRuleRemote) (ruleID *string, match bool, err error) { +func (s *ClusterScope) validateSecurityGroupRule(originalSecurityGroupRules []vpcv1.SecurityGroupRuleIntf, direction infrav1.VPCSecurityGroupRuleDirection, rule *infrav1.VPCSecurityGroupRulePrototype, remote infrav1.VPCSecurityGroupRuleRemote) (ruleID *string, match bool, err error) { //nolint: gocyclo updateError := func(e error) { err = fmt.Errorf("failed to validate VPC security group rule's remote: %w", e) } @@ -1609,8 +1615,20 @@ func (s *ClusterScope) validateSecurityGroupRule(originalSecurityGroupRules []vp for _, ogRuleIntf := range originalSecurityGroupRules { switch reflect.TypeOf(ogRuleIntf).String() { - case "*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll": - ogRule := ogRuleIntf.(*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll) + case infrav1.VPCSecurityGroupRuleProtocolAnyType: + ogRule := ogRuleIntf.(*vpcv1.SecurityGroupRuleProtocolAny) + ruleID = ogRule.ID + + if *ogRule.Direction == string(direction) && *ogRule.Protocol == protocol { + ogRemote := ogRule.Remote.(*vpcv1.SecurityGroupRuleRemote) + match, err = s.validateVPCSecurityGroupRuleRemote(ogRemote, remote) + if err != nil { + updateError(err) + return nil, false, err + } + } + case infrav1.VPCSecurityGroupRuleProtocolIcmptcpudpType: + ogRule := ogRuleIntf.(*vpcv1.SecurityGroupRuleProtocolIcmptcpudp) ruleID = ogRule.ID if *ogRule.Direction == string(direction) && *ogRule.Protocol == protocol { @@ -1621,7 +1639,7 @@ func (s *ClusterScope) validateSecurityGroupRule(originalSecurityGroupRules []vp return nil, false, err } } - case "*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp": + case infrav1.VPCSecurityGroupRuleProtocolTcpudpType: portMin := rule.PortRange.MinimumPort portMax := rule.PortRange.MaximumPort ogRule := ogRuleIntf.(*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp) @@ -1635,7 +1653,7 @@ func (s *ClusterScope) validateSecurityGroupRule(originalSecurityGroupRules []vp return nil, false, err } } - case "*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp": + case infrav1.VPCSecurityGroupRuleProtocolIcmpType: icmpCode := rule.ICMPCode icmpType := rule.ICMPType ogRule := ogRuleIntf.(*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp) @@ -1649,6 +1667,18 @@ func (s *ClusterScope) validateSecurityGroupRule(originalSecurityGroupRules []vp return nil, false, err } } + case infrav1.VPCSecurityGroupRuleProtocolIndividualType: + ogRule := ogRuleIntf.(*vpcv1.SecurityGroupRuleProtocolIndividual) + ruleID = ogRule.ID + + if *ogRule.Direction == string(direction) && *ogRule.Protocol == protocol { + ogRemote := ogRule.Remote.(*vpcv1.SecurityGroupRuleRemote) + match, err = s.validateVPCSecurityGroupRuleRemote(ogRemote, remote) + if err != nil { + updateError(err) + return nil, false, err + } + } } if match { return ruleID, match, nil diff --git a/cloud/scope/powervs/powervs_cluster_test.go b/cloud/scope/powervs/powervs_cluster_test.go index 067c42b52..434679fec 100644 --- a/cloud/scope/powervs/powervs_cluster_test.go +++ b/cloud/scope/powervs/powervs_cluster_test.go @@ -7549,7 +7549,7 @@ func TestValidateVPCSecurityGroup(t *testing.T) { Protocol: infrav1.VPCSecurityGroupRuleProtocolTCP, }, } - vpcSecurityGroupRule := vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll{ + vpcSecurityGroupRule := vpcv1.SecurityGroupRuleProtocolIcmptcpudp{ Direction: ptr.To("outbound"), Protocol: ptr.To("tcp"), Remote: &vpcv1.SecurityGroupRuleRemote{ @@ -7597,7 +7597,7 @@ func TestValidateVPCSecurityGroup(t *testing.T) { Protocol: infrav1.VPCSecurityGroupRuleProtocolTCP, }, } - vpcSecurityGroupRule := vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll{ + vpcSecurityGroupRule := vpcv1.SecurityGroupRuleProtocolIcmptcpudp{ Direction: ptr.To("outbound"), Protocol: ptr.To("tcp"), Remote: &vpcv1.SecurityGroupRuleRemote{ @@ -7864,7 +7864,7 @@ func TestValidateVPCSecurityGroup(t *testing.T) { } securityGroupDetails := &vpcv1.SecurityGroup{Name: ptr.To("securityGroupName"), ID: ptr.To("securityGroupID"), VPC: &vpcv1.VPCReference{ID: ptr.To("VPCID")}} - mockVPC.EXPECT().CreateSecurityGroupRule(gomock.Any()).Return(&vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll{Protocol: ptr.To("tcp"), ID: ptr.To("ruleID")}, nil, nil) + mockVPC.EXPECT().CreateSecurityGroupRule(gomock.Any()).Return(&vpcv1.SecurityGroupRuleProtocolIcmptcpudp{Protocol: ptr.To("tcp"), ID: ptr.To("ruleID")}, nil, nil) mockVPC.EXPECT().GetSecurityGroupByName(gomock.Any()).Return(securityGroupDetails, nil) sg, ruleIDs, err := clusterScope.validateVPCSecurityGroup(ctx, vpcSecurityGroup) g.Expect(ruleIDs).To(BeNil()) @@ -7885,7 +7885,7 @@ func TestValidateVPCSecurityGroup(t *testing.T) { Protocol: infrav1.VPCSecurityGroupRuleProtocolTCP, }, } - vpcSecurityGroupRule := vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll{ + vpcSecurityGroupRule := vpcv1.SecurityGroupRuleProtocolIcmptcpudp{ Direction: ptr.To("outbound"), Protocol: ptr.To("tcp"), Remote: &vpcv1.SecurityGroupRuleRemote{ @@ -8097,7 +8097,7 @@ func TestValidateVPCSecurityGroupRule(t *testing.T) { g.Expect(match).To(BeFalse()) g.Expect(err).ToNot(BeNil()) }) - t.Run("When it matches SecurityGroupRule of protocolType SecurityGroupRuleSecurityGroupRuleProtocolAll", func(t *testing.T) { + t.Run("When it matches SecurityGroupRule of protocolType SecurityGroupRuleProtocolIcmptcpudp", func(t *testing.T) { g := NewWithT(t) setup(t) t.Cleanup(teardown) @@ -8111,7 +8111,7 @@ func TestValidateVPCSecurityGroupRule(t *testing.T) { Protocol: infrav1.VPCSecurityGroupRuleProtocolTCP, }, } - vpcSecurityGroupRule := vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll{ + vpcSecurityGroupRule := vpcv1.SecurityGroupRuleProtocolIcmptcpudp{ Direction: ptr.To("outbound"), Protocol: ptr.To("tcp"), Remote: &vpcv1.SecurityGroupRuleRemote{ @@ -8145,7 +8145,7 @@ func TestValidateVPCSecurityGroupRule(t *testing.T) { g.Expect(match).To(BeTrue()) g.Expect(err).To(BeNil()) }) - t.Run("When it doesn't match SecurityGroupRule of protocolType SecurityGroupRuleSecurityGroupRuleProtocolAll", func(t *testing.T) { + t.Run("When it doesn't match SecurityGroupRule of protocolType SecurityGroupRuleProtocolIcmptcpudp", func(t *testing.T) { g := NewWithT(t) setup(t) t.Cleanup(teardown) @@ -8160,7 +8160,7 @@ func TestValidateVPCSecurityGroupRule(t *testing.T) { Protocol: infrav1.VPCSecurityGroupRuleProtocolTCP, }, } - vpcSecurityGroupRule := vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll{ + vpcSecurityGroupRule := vpcv1.SecurityGroupRuleProtocolIcmptcpudp{ Direction: ptr.To("outbound"), Protocol: ptr.To("tcp"), Remote: &vpcv1.SecurityGroupRuleRemote{ @@ -8194,7 +8194,7 @@ func TestValidateVPCSecurityGroupRule(t *testing.T) { g.Expect(match).To(BeFalse()) g.Expect(err).To(BeNil()) }) - t.Run("When SecurityGroupRule of protocolType SecurityGroupRuleSecurityGroupRuleProtocolAll returns error", func(t *testing.T) { + t.Run("When SecurityGroupRule of protocolType SecurityGroupRuleProtocolIcmptcpudp returns error", func(t *testing.T) { g := NewWithT(t) setup(t) t.Cleanup(teardown) @@ -8209,7 +8209,7 @@ func TestValidateVPCSecurityGroupRule(t *testing.T) { Protocol: infrav1.VPCSecurityGroupRuleProtocolTCP, }, } - vpcSecurityGroupRule := vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll{ + vpcSecurityGroupRule := vpcv1.SecurityGroupRuleProtocolIcmptcpudp{ Direction: ptr.To("outbound"), Protocol: ptr.To("tcp"), Remote: &vpcv1.SecurityGroupRuleRemote{ @@ -8402,6 +8402,312 @@ func TestValidateVPCSecurityGroupRule(t *testing.T) { g.Expect(match).To(BeFalse()) g.Expect(err).ToNot(BeNil()) }) + t.Run("When it matches SecurityGroupRule of protocolType SecurityGroupRuleProtocolAny", func(t *testing.T) { + g := NewWithT(t) + setup(t) + t.Cleanup(teardown) + + remote := infrav1.VPCSecurityGroupRuleRemote{ + RemoteType: infrav1.VPCSecurityGroupRuleRemoteTypeAny, + } + rules := infrav1.VPCSecurityGroupRule{ + Direction: infrav1.VPCSecurityGroupRuleDirectionOutbound, + Destination: &infrav1.VPCSecurityGroupRulePrototype{ + Remotes: append([]infrav1.VPCSecurityGroupRuleRemote{}, remote), + Protocol: infrav1.VPCSecurityGroupRuleProtocolAny, + }, + } + + vpcSecurityGroupRule := vpcv1.SecurityGroupRuleProtocolAny{ + Direction: ptr.To("outbound"), + Protocol: ptr.To("any"), + Remote: &vpcv1.SecurityGroupRuleRemote{ + CIDRBlock: ptr.To("0.0.0.0/0"), + }, + ID: ptr.To("ruleID"), + } + + var vpcSecurityGroupRules []vpcv1.SecurityGroupRuleIntf + vpcSecurityGroupRules = append(vpcSecurityGroupRules, &vpcSecurityGroupRule) + + vpcSecurityGroup := infrav1.VPCSecurityGroup{ + ID: ptr.To("securityGroupID"), + Rules: append([]*infrav1.VPCSecurityGroupRule{}, &rules), + } + + clusterScope := ClusterScope{ + IBMVPCClient: mockVPC, + IBMPowerVSCluster: &infrav1.IBMPowerVSCluster{ + Status: infrav1.IBMPowerVSClusterStatus{ + VPC: &infrav1.ResourceReference{ID: ptr.To("VPCID")}, + }, + Spec: infrav1.IBMPowerVSClusterSpec{ + VPCSecurityGroups: append([]infrav1.VPCSecurityGroup{}, vpcSecurityGroup), + }, + }, + } + + ruleID, match, err := clusterScope.validateSecurityGroupRule(vpcSecurityGroupRules, rules.Direction, rules.Destination, remote) + g.Expect(err).To(BeNil()) + g.Expect(match).To(BeTrue()) + g.Expect(ruleID).ToNot(BeNil()) + g.Expect(*ruleID).To(BeEquivalentTo("ruleID")) + }) + t.Run("When it doesn't match SecurityGroupRule of protocolType SecurityGroupRuleProtocolAny", func(t *testing.T) { + g := NewWithT(t) + setup(t) + t.Cleanup(teardown) + + remote := infrav1.VPCSecurityGroupRuleRemote{ + Address: ptr.To("192.168.0.1/24"), + RemoteType: infrav1.VPCSecurityGroupRuleRemoteTypeAddress, + } + rules := infrav1.VPCSecurityGroupRule{ + Direction: infrav1.VPCSecurityGroupRuleDirectionOutbound, + Destination: &infrav1.VPCSecurityGroupRulePrototype{ + Remotes: append([]infrav1.VPCSecurityGroupRuleRemote{}, remote), + Protocol: infrav1.VPCSecurityGroupRuleProtocolAny, + }, + } + + vpcSecurityGroupRule := vpcv1.SecurityGroupRuleProtocolAny{ + Direction: ptr.To("outbound"), + Protocol: ptr.To("any"), + Remote: &vpcv1.SecurityGroupRuleRemote{ + Address: ptr.To("192.168.1.1/24"), + }, + ID: ptr.To("ruleID"), + } + + var vpcSecurityGroupRules []vpcv1.SecurityGroupRuleIntf + vpcSecurityGroupRules = append(vpcSecurityGroupRules, &vpcSecurityGroupRule) + + vpcSecurityGroup := infrav1.VPCSecurityGroup{ + ID: ptr.To("securityGroupID"), + Rules: append([]*infrav1.VPCSecurityGroupRule{}, &rules), + } + clusterScope := ClusterScope{ + IBMVPCClient: mockVPC, + IBMPowerVSCluster: &infrav1.IBMPowerVSCluster{ + Status: infrav1.IBMPowerVSClusterStatus{ + VPC: &infrav1.ResourceReference{ID: ptr.To("VPCID")}, + }, + Spec: infrav1.IBMPowerVSClusterSpec{ + VPCSecurityGroups: append([]infrav1.VPCSecurityGroup{}, vpcSecurityGroup), + }, + }, + } + + ruleID, match, err := clusterScope.validateSecurityGroupRule(vpcSecurityGroupRules, rules.Direction, rules.Destination, remote) + g.Expect(err).To(BeNil()) + g.Expect(match).To(BeFalse()) + g.Expect(ruleID).To(BeNil()) + }) + + t.Run("When SecurityGroupRule of protocolType SecurityGroupRuleProtocolAny returns error", func(t *testing.T) { + g := NewWithT(t) + setup(t) + t.Cleanup(teardown) + + remote := infrav1.VPCSecurityGroupRuleRemote{ + CIDRSubnetName: ptr.To("CIDRSubnetName"), + RemoteType: infrav1.VPCSecurityGroupRuleRemoteTypeCIDR, + } + rules := infrav1.VPCSecurityGroupRule{ + Direction: infrav1.VPCSecurityGroupRuleDirectionOutbound, + Destination: &infrav1.VPCSecurityGroupRulePrototype{ + Remotes: append([]infrav1.VPCSecurityGroupRuleRemote{}, remote), + Protocol: infrav1.VPCSecurityGroupRuleProtocolAny, + }, + } + + vpcSecurityGroupRule := vpcv1.SecurityGroupRuleProtocolAny{ + Direction: ptr.To("outbound"), + Protocol: ptr.To("any"), + Remote: &vpcv1.SecurityGroupRuleRemote{ + CIDRBlock: ptr.To("192.168.1.0/24"), + }, + ID: ptr.To("ruleID"), + } + + var vpcSecurityGroupRules []vpcv1.SecurityGroupRuleIntf + vpcSecurityGroupRules = append(vpcSecurityGroupRules, &vpcSecurityGroupRule) + + vpcSecurityGroup := infrav1.VPCSecurityGroup{ + ID: ptr.To("securityGroupID"), + Rules: append([]*infrav1.VPCSecurityGroupRule{}, &rules), + } + clusterScope := ClusterScope{ + IBMVPCClient: mockVPC, + IBMPowerVSCluster: &infrav1.IBMPowerVSCluster{ + Status: infrav1.IBMPowerVSClusterStatus{ + VPC: &infrav1.ResourceReference{ID: ptr.To("VPCID")}, + }, + Spec: infrav1.IBMPowerVSClusterSpec{ + VPCSecurityGroups: append([]infrav1.VPCSecurityGroup{}, vpcSecurityGroup), + }, + }, + } + + mockVPC.EXPECT().GetVPCSubnetByName(gomock.Any()).Return(nil, errors.New("failed to get VPC subnet")) + + ruleID, match, err := clusterScope.validateSecurityGroupRule(vpcSecurityGroupRules, rules.Direction, rules.Destination, remote) + g.Expect(match).To(BeFalse()) + g.Expect(ruleID).To(BeNil()) + g.Expect(err).ToNot(BeNil()) + }) + t.Run("When it matches SecurityGroupRule of protocolType SecurityGroupRuleProtocolIndividual", func(t *testing.T) { + g := NewWithT(t) + setup(t) + t.Cleanup(teardown) + + remote := infrav1.VPCSecurityGroupRuleRemote{ + RemoteType: infrav1.VPCSecurityGroupRuleRemoteTypeAny, + } + rules := infrav1.VPCSecurityGroupRule{ + Direction: infrav1.VPCSecurityGroupRuleDirectionOutbound, + Destination: &infrav1.VPCSecurityGroupRulePrototype{ + Remotes: append([]infrav1.VPCSecurityGroupRuleRemote{}, remote), + Protocol: "gre", + }, + } + + vpcSecurityGroupRule := vpcv1.SecurityGroupRuleProtocolIndividual{ + Direction: ptr.To("outbound"), + Protocol: ptr.To("gre"), + Remote: &vpcv1.SecurityGroupRuleRemote{ + CIDRBlock: ptr.To("0.0.0.0/0"), + }, + ID: ptr.To("ruleID"), + } + + var vpcSecurityGroupRules []vpcv1.SecurityGroupRuleIntf + vpcSecurityGroupRules = append(vpcSecurityGroupRules, &vpcSecurityGroupRule) + + vpcSecurityGroup := infrav1.VPCSecurityGroup{ + ID: ptr.To("securityGroupID"), + Rules: append([]*infrav1.VPCSecurityGroupRule{}, &rules), + } + clusterScope := ClusterScope{ + IBMVPCClient: mockVPC, + IBMPowerVSCluster: &infrav1.IBMPowerVSCluster{ + Status: infrav1.IBMPowerVSClusterStatus{ + VPC: &infrav1.ResourceReference{ID: ptr.To("VPCID")}, + }, + Spec: infrav1.IBMPowerVSClusterSpec{ + VPCSecurityGroups: append([]infrav1.VPCSecurityGroup{}, vpcSecurityGroup), + }, + }, + } + + ruleID, match, err := clusterScope.validateSecurityGroupRule(vpcSecurityGroupRules, rules.Direction, rules.Destination, remote) + g.Expect(err).To(BeNil()) + g.Expect(match).To(BeTrue()) + g.Expect(ruleID).ToNot(BeNil()) + g.Expect(*ruleID).To(BeEquivalentTo("ruleID")) + }) + t.Run("When it doesn't match SecurityGroupRule of protocolType SecurityGroupRuleProtocolIndividual", func(t *testing.T) { + g := NewWithT(t) + setup(t) + t.Cleanup(teardown) + + remote := infrav1.VPCSecurityGroupRuleRemote{ + Address: ptr.To("192.168.0.1/24"), + RemoteType: infrav1.VPCSecurityGroupRuleRemoteTypeAddress, + } + rules := infrav1.VPCSecurityGroupRule{ + Direction: infrav1.VPCSecurityGroupRuleDirectionOutbound, + Destination: &infrav1.VPCSecurityGroupRulePrototype{ + Remotes: append([]infrav1.VPCSecurityGroupRuleRemote{}, remote), + Protocol: "gre", + }, + } + + vpcSecurityGroupRule := vpcv1.SecurityGroupRuleProtocolIndividual{ + Direction: ptr.To("outbound"), + Protocol: ptr.To("gre"), + Remote: &vpcv1.SecurityGroupRuleRemote{ + Address: ptr.To("192.168.1.1/24"), + }, + ID: ptr.To("ruleID"), + } + + var vpcSecurityGroupRules []vpcv1.SecurityGroupRuleIntf + vpcSecurityGroupRules = append(vpcSecurityGroupRules, &vpcSecurityGroupRule) + + vpcSecurityGroup := infrav1.VPCSecurityGroup{ + ID: ptr.To("securityGroupID"), + Rules: append([]*infrav1.VPCSecurityGroupRule{}, &rules), + } + clusterScope := ClusterScope{ + IBMVPCClient: mockVPC, + IBMPowerVSCluster: &infrav1.IBMPowerVSCluster{ + Status: infrav1.IBMPowerVSClusterStatus{ + VPC: &infrav1.ResourceReference{ID: ptr.To("VPCID")}, + }, + Spec: infrav1.IBMPowerVSClusterSpec{ + VPCSecurityGroups: append([]infrav1.VPCSecurityGroup{}, vpcSecurityGroup), + }, + }, + } + + ruleID, match, err := clusterScope.validateSecurityGroupRule(vpcSecurityGroupRules, rules.Direction, rules.Destination, remote) + g.Expect(err).To(BeNil()) + g.Expect(match).To(BeFalse()) + g.Expect(ruleID).To(BeNil()) + }) + t.Run("When SecurityGroupRule of protocolType SecurityGroupRuleProtocolIndividual returns error", func(t *testing.T) { + g := NewWithT(t) + setup(t) + t.Cleanup(teardown) + + remote := infrav1.VPCSecurityGroupRuleRemote{ + CIDRSubnetName: ptr.To("CIDRSubnetName"), + RemoteType: infrav1.VPCSecurityGroupRuleRemoteTypeCIDR, + } + rules := infrav1.VPCSecurityGroupRule{ + Direction: infrav1.VPCSecurityGroupRuleDirectionOutbound, + Destination: &infrav1.VPCSecurityGroupRulePrototype{ + Remotes: append([]infrav1.VPCSecurityGroupRuleRemote{}, remote), + Protocol: "gre", + }, + } + + vpcSecurityGroupRule := vpcv1.SecurityGroupRuleProtocolIndividual{ + Direction: ptr.To("outbound"), + Protocol: ptr.To("gre"), + Remote: &vpcv1.SecurityGroupRuleRemote{ + CIDRBlock: ptr.To("192.168.1.0/24"), + }, + ID: ptr.To("ruleID"), + } + + var vpcSecurityGroupRules []vpcv1.SecurityGroupRuleIntf + vpcSecurityGroupRules = append(vpcSecurityGroupRules, &vpcSecurityGroupRule) + + vpcSecurityGroup := infrav1.VPCSecurityGroup{ + ID: ptr.To("securityGroupID"), + Rules: append([]*infrav1.VPCSecurityGroupRule{}, &rules), + } + clusterScope := ClusterScope{ + IBMVPCClient: mockVPC, + IBMPowerVSCluster: &infrav1.IBMPowerVSCluster{ + Status: infrav1.IBMPowerVSClusterStatus{ + VPC: &infrav1.ResourceReference{ID: ptr.To("VPCID")}, + }, + Spec: infrav1.IBMPowerVSClusterSpec{ + VPCSecurityGroups: append([]infrav1.VPCSecurityGroup{}, vpcSecurityGroup), + }, + }, + } + + mockVPC.EXPECT().GetVPCSubnetByName(gomock.Any()).Return(nil, errors.New("failed to get VPC subnet")) + + ruleID, match, err := clusterScope.validateSecurityGroupRule(vpcSecurityGroupRules, rules.Direction, rules.Destination, remote) + g.Expect(match).To(BeFalse()) + g.Expect(ruleID).To(BeNil()) + g.Expect(err).ToNot(BeNil()) + }) } func TestValidateVPCSecurityGroupRules(t *testing.T) { @@ -8431,7 +8737,7 @@ func TestValidateVPCSecurityGroupRules(t *testing.T) { Protocol: infrav1.VPCSecurityGroupRuleProtocolTCP, }, } - vpcSecurityGroupRule := vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll{ + vpcSecurityGroupRule := vpcv1.SecurityGroupRuleProtocolIcmptcpudp{ Direction: ptr.To("inbound"), Protocol: ptr.To("tcp"), Remote: &vpcv1.SecurityGroupRuleRemote{ @@ -8477,7 +8783,7 @@ func TestValidateVPCSecurityGroupRules(t *testing.T) { Protocol: infrav1.VPCSecurityGroupRuleProtocolTCP, }, } - vpcSecurityGroupRule := vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll{ + vpcSecurityGroupRule := vpcv1.SecurityGroupRuleProtocolIcmptcpudp{ Direction: ptr.To("inbound"), Protocol: ptr.To("tcp"), Remote: &vpcv1.SecurityGroupRuleRemote{ @@ -8525,7 +8831,7 @@ func TestValidateVPCSecurityGroupRules(t *testing.T) { Protocol: infrav1.VPCSecurityGroupRuleProtocolTCP, }, } - vpcSecurityGroupRule := vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll{ + vpcSecurityGroupRule := vpcv1.SecurityGroupRuleProtocolIcmptcpudp{ Direction: ptr.To("inbound"), Protocol: ptr.To("tcp"), Remote: &vpcv1.SecurityGroupRuleRemote{ @@ -8572,7 +8878,7 @@ func TestValidateVPCSecurityGroupRules(t *testing.T) { Protocol: infrav1.VPCSecurityGroupRuleProtocolTCP, }, } - vpcSecurityGroupRule := vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll{ + vpcSecurityGroupRule := vpcv1.SecurityGroupRuleProtocolIcmptcpudp{ Direction: ptr.To("outbound"), Protocol: ptr.To("tcp"), Remote: &vpcv1.SecurityGroupRuleRemote{ @@ -8618,7 +8924,7 @@ func TestValidateVPCSecurityGroupRules(t *testing.T) { Protocol: infrav1.VPCSecurityGroupRuleProtocolTCP, }, } - vpcSecurityGroupRule := vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll{ + vpcSecurityGroupRule := vpcv1.SecurityGroupRuleProtocolIcmptcpudp{ Direction: ptr.To("outbound"), Protocol: ptr.To("tcp"), Remote: &vpcv1.SecurityGroupRuleRemote{ @@ -9093,7 +9399,7 @@ func TestCreateVPCSecurityGroupRule(t *testing.T) { }, } - mockVPC.EXPECT().CreateSecurityGroupRule(gomock.Any()).Return(&vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll{Direction: ptr.To("outbound"), ID: ptr.To("ruleID")}, nil, nil) + mockVPC.EXPECT().CreateSecurityGroupRule(gomock.Any()).Return(&vpcv1.SecurityGroupRuleProtocolIcmptcpudp{Direction: ptr.To("outbound"), ID: ptr.To("ruleID")}, nil, nil) ruleID, err := clusterScope.createVPCSecurityGroupRule(ctx, &securityGroupID, ptr.To("outbound"), &protocol, &portMin, &portMax, remote) g.Expect(ruleID).To(BeEquivalentTo(ptr.To("ruleID"))) g.Expect(err).To(BeNil()) @@ -9207,7 +9513,7 @@ func TestCreateVPCSecurityGroupRule(t *testing.T) { }, } - mockVPC.EXPECT().CreateSecurityGroupRule(gomock.Any()).Return(&vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll{Direction: ptr.To("outbound"), ID: ptr.To("ruleID")}, nil, nil) + mockVPC.EXPECT().CreateSecurityGroupRule(gomock.Any()).Return(&vpcv1.SecurityGroupRuleProtocolIcmptcpudp{Direction: ptr.To("outbound"), ID: ptr.To("ruleID")}, nil, nil) ruleID, err := clusterScope.createVPCSecurityGroupRule(ctx, &securityGroupID, ptr.To("outbound"), &protocol, &portMin, &portMax, remote) g.Expect(ruleID).To(BeEquivalentTo(ptr.To("ruleID"))) g.Expect(err).To(BeNil()) @@ -9548,7 +9854,7 @@ func TestCreateVPCSecurityGroupRulesAndSetStatus(t *testing.T) { }, } - mockVPC.EXPECT().CreateSecurityGroupRule(gomock.Any()).Return(&vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll{Direction: ptr.To("outbound"), ID: ptr.To("ruleID")}, nil, nil) + mockVPC.EXPECT().CreateSecurityGroupRule(gomock.Any()).Return(&vpcv1.SecurityGroupRuleProtocolIcmptcpudp{Direction: ptr.To("outbound"), ID: ptr.To("ruleID")}, nil, nil) err := clusterScope.createVPCSecurityGroupRulesAndSetStatus(ctx, vpcSecurityGroup.Rules, ptr.To("securityGroupID"), ptr.To("securityGroupName")) g.Expect(err).To(BeNil()) }) diff --git a/cloud/scope/vpc/cluster_v2.go b/cloud/scope/vpc/cluster_v2.go index 78031c80c..7f879c86a 100644 --- a/cloud/scope/vpc/cluster_v2.go +++ b/cloud/scope/vpc/cluster_v2.go @@ -22,6 +22,7 @@ import ( "fmt" "net/http" "reflect" + "regexp" "github.com/go-logr/logr" @@ -61,6 +62,14 @@ const ( privateLBSuffix = "private" // publicLBSuffix is used to tag a default Load Balancer name as public. publicLBSuffix = "public" + + // individualSgrRegex is used to check if the VPCSecurityGroupRuleProtocolIndividual is valid. + individualSgrRegex = "^(ah|esp|gre|ip_in_ip|l2tp|rsvp|sctp|vrrp|number_(?:0|2|3|5|[7-9]|1[0-6]|1[8-9]|[2-3][0-9]|4[0-5]|4[89]|5[2-9]|[6-9][0-9]|10[0-9]|11[0-1]|11[3-4]|11[6-9]|12[0-9]|13[0-1]|13[3-9]|1[4-9][0-9]|2[0-4][0-9]|25[0-5]))$" +) + +var ( + // Compile the regexp object for the VPCSecurityGroupRuleProtocolIndividualType. + individualSgrRegexp = regexp.MustCompile(individualSgrRegex) ) // ClusterScopeParamsV2 defines the input parameters used to create a new ClusterScopeV2. @@ -1455,22 +1464,40 @@ func (s *ClusterScopeV2) findOrCreateSecurityGroupRule(ctx context.Context, secu for _, existingRuleIntf := range existingSecurityGroupRules.Rules { // Perform analysis of the existingRuleIntf, based on its Protocol type, further analysis is performed based on remaining attributes to find if the specific Rule and Remote match switch reflect.TypeOf(existingRuleIntf).String() { - case infrav1.VPCSecurityGroupRuleProtocolAllType: - // If our Remote doesn't define all Protocols, we don't need further checks, move on to next Rule - if securityGroupRulePrototype.Protocol != infrav1.VPCSecurityGroupRuleProtocolAll { + case infrav1.VPCSecurityGroupRuleProtocolAnyType: + // If our Remote doesn't define the Any Protocol, we don't need further checks, move on to next Rule + if securityGroupRulePrototype.Protocol != infrav1.VPCSecurityGroupRuleProtocolAny { continue } - existingRule := existingRuleIntf.(*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll) + existingRule := existingRuleIntf.(*vpcv1.SecurityGroupRuleProtocolAny) // If the Remote doesn't have the same Direction as the Rule, no further checks are necessary if securityGroupRule.Direction != infrav1.VPCSecurityGroupRuleDirection(*existingRule.Direction) { continue } - if found, err := s.checkSecurityGroupRuleProtocolAll(ctx, securityGroupRulePrototype, remote, existingRule); err != nil { - return fmt.Errorf("error failure checking security group rule protocol all: %w", err) + if found, err := s.checkSecurityGroupRuleProtocolAny(ctx, securityGroupRulePrototype, remote, existingRule); err != nil { + return fmt.Errorf("error failure checking security group rule protocol any: %w", err) } else if found { // If we found the matching IBM Cloud Security Group Rule for the defined SecurityGroupRule and Remote, we can stop checking IBM Cloud Security Group Rules for this remote and move onto the next remote. // The expectation is that only one IBM Cloud Security Group Rule will match, but if at least one matches the defined SecurityGroupRule, that is sufficient. - log.V(3).Info("security group rule all protocol match found") + log.V(3).Info("security group rule any protocol match found") + remoteMatch = true + break + } + case infrav1.VPCSecurityGroupRuleProtocolIcmptcpudpType: + // If our Remote doesn't define icmp_tcp_udp Protocols, we don't need further checks, move on to next Rule + if securityGroupRulePrototype.Protocol != infrav1.VPCSecurityGroupRuleProtocolIcmpTCPUDP { + continue + } + existingRule := existingRuleIntf.(*vpcv1.SecurityGroupRuleProtocolIcmptcpudp) + // If the Remote doesn't have the same Direction as the Rule, no further checks are necessary + if securityGroupRule.Direction != infrav1.VPCSecurityGroupRuleDirection(*existingRule.Direction) { + continue + } + if found, err := s.checkSecurityGroupRuleProtocolIcmpTCPUDP(ctx, securityGroupRulePrototype, remote, existingRule); err != nil { + return fmt.Errorf("error failure checking security group rule protocol icmp_tcp_udp: %w", err) + } else if found { + // If we found the matching IBM Cloud Security Group Rule for the defined SecurityGroupRule and Remote, we can stop checking IBM Cloud Security Group Rules for this remote and move onto the next remote. + log.V(3).Info("security group rule icmp_tcp_udp protocol match found") remoteMatch = true break } @@ -1510,6 +1537,26 @@ func (s *ClusterScopeV2) findOrCreateSecurityGroupRule(ctx context.Context, secu remoteMatch = true break } + case infrav1.VPCSecurityGroupRuleProtocolIndividualType: + matched := individualSgrRegexp.MatchString(string(securityGroupRulePrototype.Protocol)) + + // If our Remote doesn't define one of the individual Protocol, we don't need further checks, move on to next Rule + if !matched { + continue + } + existingRule := existingRuleIntf.(*vpcv1.SecurityGroupRuleProtocolIndividual) + // If the Remote doesn't have the same Direction as the Rule, no further checks are necessary + if securityGroupRule.Direction != infrav1.VPCSecurityGroupRuleDirection(*existingRule.Direction) { + continue + } + if found, err := s.checkSecurityGroupRuleProtocolIndividual(ctx, securityGroupRulePrototype, remote, existingRule); err != nil { + return fmt.Errorf("error failure checking security group rule protocol %s: %w", string(securityGroupRulePrototype.Protocol), err) // TODO: Which protocol should be part of the error message? + } else if found { + // If we found the matching IBM Cloud Security Group Rule for the defined SecurityGroupRule and Remote, we can stop checking IBM Cloud Security Group Rules for this remote and move onto the next remote. + log.V(3).Info("security group rule individual protocol match found", "protocol", string(securityGroupRulePrototype.Protocol)) + remoteMatch = true + break + } default: // This is an unexpected IBM Cloud Security Group Rule Prototype, log it and move on log.V(3).Info("unexpected security group rule prototype", "securityGroupRulePrototype", reflect.TypeOf(existingRuleIntf).String()) @@ -1527,13 +1574,25 @@ func (s *ClusterScopeV2) findOrCreateSecurityGroupRule(ctx context.Context, secu return nil } -// checkSecurityGroupRuleProtocolAll analyzes an IBM Cloud Security Group Rule designated for 'all' protocols, to verify if the supplied Rule and Remote match the attributes from the existing 'ProtocolAll' Rule. -func (s *ClusterScopeV2) checkSecurityGroupRuleProtocolAll(ctx context.Context, _ infrav1.VPCSecurityGroupRulePrototype, securityGroupRuleRemote infrav1.VPCSecurityGroupRuleRemote, existingRule *vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll) (bool, error) { +// checkSecurityGroupRuleProtocolAny analyzes an IBM Cloud Security Group Rule designated for 'any' protocols, to verify if the supplied Rule and Remote match the attributes from the existing 'any' Rule. +func (s *ClusterScopeV2) checkSecurityGroupRuleProtocolAny(ctx context.Context, _ infrav1.VPCSecurityGroupRulePrototype, securityGroupRuleRemote infrav1.VPCSecurityGroupRuleRemote, existingRule *vpcv1.SecurityGroupRuleProtocolAny) (bool, error) { + log := ctrl.LoggerFrom(ctx) + if exists, err := s.checkSecurityGroupRulePrototypeRemote(ctx, securityGroupRuleRemote, existingRule.Remote); err != nil { + return false, fmt.Errorf("error failed checking security group rule any remote: %w", err) + } else if exists { + log.V(3).Info("security group rule any protocol matches") + return true, nil + } + return false, nil +} + +// checkSecurityGroupRuleProtocolIcmpTCPUDP analyzes an IBM Cloud Security Group Rule designated for 'icmp_tcp_udp' protocols, to verify if the supplied Rule and Remote match the attributes from the existing 'icmp_tcp_udp' Rule. +func (s *ClusterScopeV2) checkSecurityGroupRuleProtocolIcmpTCPUDP(ctx context.Context, _ infrav1.VPCSecurityGroupRulePrototype, securityGroupRuleRemote infrav1.VPCSecurityGroupRuleRemote, existingRule *vpcv1.SecurityGroupRuleProtocolIcmptcpudp) (bool, error) { log := ctrl.LoggerFrom(ctx) if exists, err := s.checkSecurityGroupRulePrototypeRemote(ctx, securityGroupRuleRemote, existingRule.Remote); err != nil { - return false, fmt.Errorf("error failed checking security group rule all remote: %w", err) + return false, fmt.Errorf("error failed checking security group rule icmp-tcp-udp remote: %w", err) } else if exists { - log.V(3).Info("security group rule all protocols match") + log.V(3).Info("security group rule icmp-tcp-udp protocol matches") return true, nil } return false, nil @@ -1583,6 +1642,23 @@ func (s *ClusterScopeV2) checkSecurityGroupRuleProtocolTcpudp(ctx context.Contex return false, nil } +// checkSecurityGroupRuleProtocolIndividual analyzes an IBM Cloud Security Group Rule designated for individual protocols, to verify if the supplied Rule and Remote match the attributes from the existing individual Rule. +func (s *ClusterScopeV2) checkSecurityGroupRuleProtocolIndividual(ctx context.Context, securityGroupRulePrototype infrav1.VPCSecurityGroupRulePrototype, securityGroupRuleRemote infrav1.VPCSecurityGroupRuleRemote, existingRule *vpcv1.SecurityGroupRuleProtocolIndividual) (bool, error) { + log := ctrl.LoggerFrom(ctx) + // Check the protocol next to verify it matches + if securityGroupRulePrototype.Protocol != infrav1.VPCSecurityGroupRuleProtocol(*existingRule.Protocol) { + return false, nil + } + + if exists, err := s.checkSecurityGroupRulePrototypeRemote(ctx, securityGroupRuleRemote, existingRule.Remote); err != nil { + return false, fmt.Errorf("error failed checking security group rule %s remote: %w", string(securityGroupRulePrototype.Protocol), err) + } else if exists { + log.V(3).Info("security group rule individual protocol matches", "protocol", string(securityGroupRulePrototype.Protocol)) + return true, nil + } + return false, nil +} + func (s *ClusterScopeV2) checkSecurityGroupRulePrototypeRemote(ctx context.Context, securityGroupRuleRemote infrav1.VPCSecurityGroupRuleRemote, existingRemote vpcv1.SecurityGroupRuleRemoteIntf) (bool, error) { //nolint: gocyclo log := ctrl.LoggerFrom(ctx) // NOTE(cjschaef): We only currently monitor Remote, not Local, as we don't support defining Local in SecurityGroup/SecurityGroupRule. @@ -1706,8 +1782,15 @@ func (s *ClusterScopeV2) createSecurityGroupRule(ctx context.Context, securityGr return fmt.Errorf("error failed to create security group rule remote: %w", err) } switch securityGroupRulePrototype.Protocol { - case infrav1.VPCSecurityGroupRuleProtocolAll: - prototype := &vpcv1.SecurityGroupRulePrototypeSecurityGroupRuleProtocolAll{ + case infrav1.VPCSecurityGroupRuleProtocolAny: + prototype := &vpcv1.SecurityGroupRulePrototypeSecurityGroupRuleProtocolAnyPrototype{ + Direction: ptr.To(string(securityGroupRule.Direction)), + Protocol: ptr.To(string(securityGroupRulePrototype.Protocol)), + Remote: prototypeRemote, + } + options.SetSecurityGroupRulePrototype(prototype) + case infrav1.VPCSecurityGroupRuleProtocolIcmpTCPUDP: + prototype := &vpcv1.SecurityGroupRulePrototypeSecurityGroupRuleProtocolIcmptcpudpPrototype{ Direction: ptr.To(string(securityGroupRule.Direction)), Protocol: ptr.To(string(securityGroupRulePrototype.Protocol)), Remote: prototypeRemote, @@ -1738,8 +1821,21 @@ func (s *ClusterScopeV2) createSecurityGroupRule(ctx context.Context, securityGr } options.SetSecurityGroupRulePrototype(prototype) default: - // This should not be possible, provided the strict kubebuilder enforcements - return fmt.Errorf("error failed creating security group rule, unknown protocol") + // Check if protocol is part of the supported list else error + // If part of the supported list add it as Individual prototype + matched := individualSgrRegexp.MatchString(string(securityGroupRulePrototype.Protocol)) + + if matched { + prototype := &vpcv1.SecurityGroupRulePrototypeSecurityGroupRuleProtocolIndividualPrototype{ + Direction: ptr.To(string(securityGroupRule.Direction)), + Protocol: ptr.To(string(securityGroupRulePrototype.Protocol)), + Remote: prototypeRemote, + } + options.SetSecurityGroupRulePrototype(prototype) + } else { + // This should not be possible, provided the strict kubebuilder enforcements + return fmt.Errorf("error failed creating security group rule, unknown protocol") + } } log.V(3).Info("Creating Security Group Rule for Security Group", "securityGroupID", securityGroupID, "direction", securityGroupRule.Direction, "protocol", securityGroupRulePrototype.Protocol, "prototypeRemote", prototypeRemote) @@ -1753,8 +1849,11 @@ func (s *ClusterScopeV2) createSecurityGroupRule(ctx context.Context, securityGr // Typecast the resulting SecurityGroupRuleIntf, to retrieve the ID for logging var ruleID *string switch reflect.TypeOf(securityGroupRuleIntfDetails).String() { - case infrav1.VPCSecurityGroupRuleProtocolAllType: - rule := securityGroupRuleIntfDetails.(*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolAll) + case infrav1.VPCSecurityGroupRuleProtocolAnyType: + rule := securityGroupRuleIntfDetails.(*vpcv1.SecurityGroupRuleProtocolAny) + ruleID = rule.ID + case infrav1.VPCSecurityGroupRuleProtocolIcmptcpudpType: + rule := securityGroupRuleIntfDetails.(*vpcv1.SecurityGroupRuleProtocolIcmptcpudp) ruleID = rule.ID case infrav1.VPCSecurityGroupRuleProtocolIcmpType: rule := securityGroupRuleIntfDetails.(*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolIcmp) @@ -1762,6 +1861,9 @@ func (s *ClusterScopeV2) createSecurityGroupRule(ctx context.Context, securityGr case infrav1.VPCSecurityGroupRuleProtocolTcpudpType: rule := securityGroupRuleIntfDetails.(*vpcv1.SecurityGroupRuleSecurityGroupRuleProtocolTcpudp) ruleID = rule.ID + case infrav1.VPCSecurityGroupRuleProtocolIndividualType: + rule := securityGroupRuleIntfDetails.(*vpcv1.SecurityGroupRuleProtocolIndividual) + ruleID = rule.ID } log.V(3).Info("Created Security Group Rule", "ruleID", ruleID) return nil diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmpowervsclusters.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmpowervsclusters.yaml index 4e928c403..bbc05e0ec 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmpowervsclusters.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmpowervsclusters.yaml @@ -599,11 +599,7 @@ spec: protocol: description: protocol defines the traffic protocol used for the Security Group Rule. - enum: - - all - - icmp - - tcp - - udp + pattern: ^(any|icmp_tcp_udp|icmp|tcp|udp|ah|esp|gre|ip_in_ip|l2tp|rsvp|sctp|vrrp|number_(?:0|2|3|5|[7-9]|1[0-6]|1[8-9]|[2-3][0-9]|4[0-5]|4[89]|5[2-9]|[6-9][0-9]|10[0-9]|11[0-1]|11[3-4]|11[6-9]|12[0-9]|13[0-1]|13[3-9]|1[4-9][0-9]|2[0-4][0-9]|25[0-5]))$ type: string remotes: description: |- @@ -674,14 +670,17 @@ spec: VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol != ''icmp'' ? (!has(self.icmpCode) && !has(self.icmpType)) : true' - - message: portRange is not valid for VPCSecurityGroupRuleProtocolAll - protocol - rule: 'self.protocol == ''all'' ? !has(self.portRange) - : true' - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol == ''icmp'' ? !has(self.portRange) : true' + - message: portRange is not valid for protocol + rule: '(self.protocol != ''tcp'' && self.protocol != + ''udp'') ? !has(self.portRange) : true' + - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmpTCPUDP + protocol + rule: 'self.protocol == ''icmp_tcp_udp'' ? !has(self.portRange) + : true' direction: description: direction defines whether the traffic is inbound or outbound for the Security Group Rule. @@ -736,11 +735,7 @@ spec: protocol: description: protocol defines the traffic protocol used for the Security Group Rule. - enum: - - all - - icmp - - tcp - - udp + pattern: ^(any|icmp_tcp_udp|icmp|tcp|udp|ah|esp|gre|ip_in_ip|l2tp|rsvp|sctp|vrrp|number_(?:0|2|3|5|[7-9]|1[0-6]|1[8-9]|[2-3][0-9]|4[0-5]|4[89]|5[2-9]|[6-9][0-9]|10[0-9]|11[0-1]|11[3-4]|11[6-9]|12[0-9]|13[0-1]|13[3-9]|1[4-9][0-9]|2[0-4][0-9]|25[0-5]))$ type: string remotes: description: |- @@ -811,14 +806,17 @@ spec: VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol != ''icmp'' ? (!has(self.icmpCode) && !has(self.icmpType)) : true' - - message: portRange is not valid for VPCSecurityGroupRuleProtocolAll - protocol - rule: 'self.protocol == ''all'' ? !has(self.portRange) - : true' - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol == ''icmp'' ? !has(self.portRange) : true' + - message: portRange is not valid for protocol + rule: '(self.protocol != ''tcp'' && self.protocol != + ''udp'') ? !has(self.portRange) : true' + - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmpTCPUDP + protocol + rule: 'self.protocol == ''icmp_tcp_udp'' ? !has(self.portRange) + : true' required: - action - direction @@ -1783,11 +1781,7 @@ spec: protocol: description: protocol defines the traffic protocol used for the Security Group Rule. - enum: - - all - - icmp - - tcp - - udp + pattern: ^(any|icmp_tcp_udp|icmp|tcp|udp|ah|esp|gre|ip_in_ip|l2tp|rsvp|sctp|vrrp|number_(?:0|2|3|5|[7-9]|1[0-6]|1[8-9]|[2-3][0-9]|4[0-5]|4[89]|5[2-9]|[6-9][0-9]|10[0-9]|11[0-1]|11[3-4]|11[6-9]|12[0-9]|13[0-1]|13[3-9]|1[4-9][0-9]|2[0-4][0-9]|25[0-5]))$ type: string remotes: description: |- @@ -1858,14 +1852,17 @@ spec: VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol != ''icmp'' ? (!has(self.icmpCode) && !has(self.icmpType)) : true' - - message: portRange is not valid for VPCSecurityGroupRuleProtocolAll - protocol - rule: 'self.protocol == ''all'' ? !has(self.portRange) - : true' - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol == ''icmp'' ? !has(self.portRange) : true' + - message: portRange is not valid for protocol + rule: '(self.protocol != ''tcp'' && self.protocol != + ''udp'') ? !has(self.portRange) : true' + - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmpTCPUDP + protocol + rule: 'self.protocol == ''icmp_tcp_udp'' ? !has(self.portRange) + : true' direction: description: direction defines whether the traffic is inbound or outbound for the Security Group Rule. @@ -1920,11 +1917,7 @@ spec: protocol: description: protocol defines the traffic protocol used for the Security Group Rule. - enum: - - all - - icmp - - tcp - - udp + pattern: ^(any|icmp_tcp_udp|icmp|tcp|udp|ah|esp|gre|ip_in_ip|l2tp|rsvp|sctp|vrrp|number_(?:0|2|3|5|[7-9]|1[0-6]|1[8-9]|[2-3][0-9]|4[0-5]|4[89]|5[2-9]|[6-9][0-9]|10[0-9]|11[0-1]|11[3-4]|11[6-9]|12[0-9]|13[0-1]|13[3-9]|1[4-9][0-9]|2[0-4][0-9]|25[0-5]))$ type: string remotes: description: |- @@ -1995,14 +1988,17 @@ spec: VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol != ''icmp'' ? (!has(self.icmpCode) && !has(self.icmpType)) : true' - - message: portRange is not valid for VPCSecurityGroupRuleProtocolAll - protocol - rule: 'self.protocol == ''all'' ? !has(self.portRange) - : true' - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol == ''icmp'' ? !has(self.portRange) : true' + - message: portRange is not valid for protocol + rule: '(self.protocol != ''tcp'' && self.protocol != + ''udp'') ? !has(self.portRange) : true' + - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmpTCPUDP + protocol + rule: 'self.protocol == ''icmp_tcp_udp'' ? !has(self.portRange) + : true' required: - action - direction diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmpowervsclustertemplates.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmpowervsclustertemplates.yaml index 9128cfb4e..9c25a6d12 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmpowervsclustertemplates.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmpowervsclustertemplates.yaml @@ -623,11 +623,7 @@ spec: protocol: description: protocol defines the traffic protocol used for the Security Group Rule. - enum: - - all - - icmp - - tcp - - udp + pattern: ^(any|icmp_tcp_udp|icmp|tcp|udp|ah|esp|gre|ip_in_ip|l2tp|rsvp|sctp|vrrp|number_(?:0|2|3|5|[7-9]|1[0-6]|1[8-9]|[2-3][0-9]|4[0-5]|4[89]|5[2-9]|[6-9][0-9]|10[0-9]|11[0-1]|11[3-4]|11[6-9]|12[0-9]|13[0-1]|13[3-9]|1[4-9][0-9]|2[0-4][0-9]|25[0-5]))$ type: string remotes: description: |- @@ -701,14 +697,17 @@ spec: for VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol != ''icmp'' ? (!has(self.icmpCode) && !has(self.icmpType)) : true' - - message: portRange is not valid for VPCSecurityGroupRuleProtocolAll - protocol - rule: 'self.protocol == ''all'' ? !has(self.portRange) - : true' - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol == ''icmp'' ? !has(self.portRange) : true' + - message: portRange is not valid for protocol + rule: '(self.protocol != ''tcp'' && self.protocol + != ''udp'') ? !has(self.portRange) : true' + - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmpTCPUDP + protocol + rule: 'self.protocol == ''icmp_tcp_udp'' ? !has(self.portRange) + : true' direction: description: direction defines whether the traffic is inbound or outbound for the Security Group @@ -764,11 +763,7 @@ spec: protocol: description: protocol defines the traffic protocol used for the Security Group Rule. - enum: - - all - - icmp - - tcp - - udp + pattern: ^(any|icmp_tcp_udp|icmp|tcp|udp|ah|esp|gre|ip_in_ip|l2tp|rsvp|sctp|vrrp|number_(?:0|2|3|5|[7-9]|1[0-6]|1[8-9]|[2-3][0-9]|4[0-5]|4[89]|5[2-9]|[6-9][0-9]|10[0-9]|11[0-1]|11[3-4]|11[6-9]|12[0-9]|13[0-1]|13[3-9]|1[4-9][0-9]|2[0-4][0-9]|25[0-5]))$ type: string remotes: description: |- @@ -842,14 +837,17 @@ spec: for VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol != ''icmp'' ? (!has(self.icmpCode) && !has(self.icmpType)) : true' - - message: portRange is not valid for VPCSecurityGroupRuleProtocolAll - protocol - rule: 'self.protocol == ''all'' ? !has(self.portRange) - : true' - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol == ''icmp'' ? !has(self.portRange) : true' + - message: portRange is not valid for protocol + rule: '(self.protocol != ''tcp'' && self.protocol + != ''udp'') ? !has(self.portRange) : true' + - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmpTCPUDP + protocol + rule: 'self.protocol == ''icmp_tcp_udp'' ? !has(self.portRange) + : true' required: - action - direction @@ -1538,11 +1536,7 @@ spec: protocol: description: protocol defines the traffic protocol used for the Security Group Rule. - enum: - - all - - icmp - - tcp - - udp + pattern: ^(any|icmp_tcp_udp|icmp|tcp|udp|ah|esp|gre|ip_in_ip|l2tp|rsvp|sctp|vrrp|number_(?:0|2|3|5|[7-9]|1[0-6]|1[8-9]|[2-3][0-9]|4[0-5]|4[89]|5[2-9]|[6-9][0-9]|10[0-9]|11[0-1]|11[3-4]|11[6-9]|12[0-9]|13[0-1]|13[3-9]|1[4-9][0-9]|2[0-4][0-9]|25[0-5]))$ type: string remotes: description: |- @@ -1616,14 +1610,17 @@ spec: for VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol != ''icmp'' ? (!has(self.icmpCode) && !has(self.icmpType)) : true' - - message: portRange is not valid for VPCSecurityGroupRuleProtocolAll - protocol - rule: 'self.protocol == ''all'' ? !has(self.portRange) - : true' - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol == ''icmp'' ? !has(self.portRange) : true' + - message: portRange is not valid for protocol + rule: '(self.protocol != ''tcp'' && self.protocol + != ''udp'') ? !has(self.portRange) : true' + - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmpTCPUDP + protocol + rule: 'self.protocol == ''icmp_tcp_udp'' ? !has(self.portRange) + : true' direction: description: direction defines whether the traffic is inbound or outbound for the Security Group @@ -1679,11 +1676,7 @@ spec: protocol: description: protocol defines the traffic protocol used for the Security Group Rule. - enum: - - all - - icmp - - tcp - - udp + pattern: ^(any|icmp_tcp_udp|icmp|tcp|udp|ah|esp|gre|ip_in_ip|l2tp|rsvp|sctp|vrrp|number_(?:0|2|3|5|[7-9]|1[0-6]|1[8-9]|[2-3][0-9]|4[0-5]|4[89]|5[2-9]|[6-9][0-9]|10[0-9]|11[0-1]|11[3-4]|11[6-9]|12[0-9]|13[0-1]|13[3-9]|1[4-9][0-9]|2[0-4][0-9]|25[0-5]))$ type: string remotes: description: |- @@ -1757,14 +1750,17 @@ spec: for VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol != ''icmp'' ? (!has(self.icmpCode) && !has(self.icmpType)) : true' - - message: portRange is not valid for VPCSecurityGroupRuleProtocolAll - protocol - rule: 'self.protocol == ''all'' ? !has(self.portRange) - : true' - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol == ''icmp'' ? !has(self.portRange) : true' + - message: portRange is not valid for protocol + rule: '(self.protocol != ''tcp'' && self.protocol + != ''udp'') ? !has(self.portRange) : true' + - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmpTCPUDP + protocol + rule: 'self.protocol == ''icmp_tcp_udp'' ? !has(self.portRange) + : true' required: - action - direction diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmvpcclusters.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmvpcclusters.yaml index f9277a95d..0d28bc190 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmvpcclusters.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmvpcclusters.yaml @@ -898,11 +898,7 @@ spec: protocol: description: protocol defines the traffic protocol used for the Security Group Rule. - enum: - - all - - icmp - - tcp - - udp + pattern: ^(any|icmp_tcp_udp|icmp|tcp|udp|ah|esp|gre|ip_in_ip|l2tp|rsvp|sctp|vrrp|number_(?:0|2|3|5|[7-9]|1[0-6]|1[8-9]|[2-3][0-9]|4[0-5]|4[89]|5[2-9]|[6-9][0-9]|10[0-9]|11[0-1]|11[3-4]|11[6-9]|12[0-9]|13[0-1]|13[3-9]|1[4-9][0-9]|2[0-4][0-9]|25[0-5]))$ type: string remotes: description: |- @@ -973,14 +969,17 @@ spec: for VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol != ''icmp'' ? (!has(self.icmpCode) && !has(self.icmpType)) : true' - - message: portRange is not valid for VPCSecurityGroupRuleProtocolAll - protocol - rule: 'self.protocol == ''all'' ? !has(self.portRange) - : true' - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol == ''icmp'' ? !has(self.portRange) : true' + - message: portRange is not valid for protocol + rule: '(self.protocol != ''tcp'' && self.protocol + != ''udp'') ? !has(self.portRange) : true' + - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmpTCPUDP + protocol + rule: 'self.protocol == ''icmp_tcp_udp'' ? !has(self.portRange) + : true' direction: description: direction defines whether the traffic is inbound or outbound for the Security Group Rule. @@ -1035,11 +1034,7 @@ spec: protocol: description: protocol defines the traffic protocol used for the Security Group Rule. - enum: - - all - - icmp - - tcp - - udp + pattern: ^(any|icmp_tcp_udp|icmp|tcp|udp|ah|esp|gre|ip_in_ip|l2tp|rsvp|sctp|vrrp|number_(?:0|2|3|5|[7-9]|1[0-6]|1[8-9]|[2-3][0-9]|4[0-5]|4[89]|5[2-9]|[6-9][0-9]|10[0-9]|11[0-1]|11[3-4]|11[6-9]|12[0-9]|13[0-1]|13[3-9]|1[4-9][0-9]|2[0-4][0-9]|25[0-5]))$ type: string remotes: description: |- @@ -1110,14 +1105,17 @@ spec: for VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol != ''icmp'' ? (!has(self.icmpCode) && !has(self.icmpType)) : true' - - message: portRange is not valid for VPCSecurityGroupRuleProtocolAll - protocol - rule: 'self.protocol == ''all'' ? !has(self.portRange) - : true' - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol == ''icmp'' ? !has(self.portRange) : true' + - message: portRange is not valid for protocol + rule: '(self.protocol != ''tcp'' && self.protocol + != ''udp'') ? !has(self.portRange) : true' + - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmpTCPUDP + protocol + rule: 'self.protocol == ''icmp_tcp_udp'' ? !has(self.portRange) + : true' required: - action - direction diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmvpcclustertemplates.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmvpcclustertemplates.yaml index 9376c7ae3..631e0cc33 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmvpcclustertemplates.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmvpcclustertemplates.yaml @@ -757,11 +757,7 @@ spec: description: protocol defines the traffic protocol used for the Security Group Rule. - enum: - - all - - icmp - - tcp - - udp + pattern: ^(any|icmp_tcp_udp|icmp|tcp|udp|ah|esp|gre|ip_in_ip|l2tp|rsvp|sctp|vrrp|number_(?:0|2|3|5|[7-9]|1[0-6]|1[8-9]|[2-3][0-9]|4[0-5]|4[89]|5[2-9]|[6-9][0-9]|10[0-9]|11[0-1]|11[3-4]|11[6-9]|12[0-9]|13[0-1]|13[3-9]|1[4-9][0-9]|2[0-4][0-9]|25[0-5]))$ type: string remotes: description: |- @@ -842,14 +838,17 @@ spec: protocol rule: 'self.protocol != ''icmp'' ? (!has(self.icmpCode) && !has(self.icmpType)) : true' - - message: portRange is not valid for VPCSecurityGroupRuleProtocolAll - protocol - rule: 'self.protocol == ''all'' ? !has(self.portRange) - : true' - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol == ''icmp'' ? !has(self.portRange) : true' + - message: portRange is not valid for protocol + rule: '(self.protocol != ''tcp'' && self.protocol + != ''udp'') ? !has(self.portRange) : true' + - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmpTCPUDP + protocol + rule: 'self.protocol == ''icmp_tcp_udp'' + ? !has(self.portRange) : true' direction: description: direction defines whether the traffic is inbound or outbound for the Security @@ -907,11 +906,7 @@ spec: description: protocol defines the traffic protocol used for the Security Group Rule. - enum: - - all - - icmp - - tcp - - udp + pattern: ^(any|icmp_tcp_udp|icmp|tcp|udp|ah|esp|gre|ip_in_ip|l2tp|rsvp|sctp|vrrp|number_(?:0|2|3|5|[7-9]|1[0-6]|1[8-9]|[2-3][0-9]|4[0-5]|4[89]|5[2-9]|[6-9][0-9]|10[0-9]|11[0-1]|11[3-4]|11[6-9]|12[0-9]|13[0-1]|13[3-9]|1[4-9][0-9]|2[0-4][0-9]|25[0-5]))$ type: string remotes: description: |- @@ -992,14 +987,17 @@ spec: protocol rule: 'self.protocol != ''icmp'' ? (!has(self.icmpCode) && !has(self.icmpType)) : true' - - message: portRange is not valid for VPCSecurityGroupRuleProtocolAll - protocol - rule: 'self.protocol == ''all'' ? !has(self.portRange) - : true' - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmp protocol rule: 'self.protocol == ''icmp'' ? !has(self.portRange) : true' + - message: portRange is not valid for protocol + rule: '(self.protocol != ''tcp'' && self.protocol + != ''udp'') ? !has(self.portRange) : true' + - message: portRange is not valid for VPCSecurityGroupRuleProtocolIcmpTCPUDP + protocol + rule: 'self.protocol == ''icmp_tcp_udp'' + ? !has(self.portRange) : true' required: - action - direction diff --git a/go.mod b/go.mod index a34affe8c..8f0a9a75c 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/IBM/ibm-cos-sdk-go v1.13.0 github.com/IBM/networking-go-sdk v0.51.15 github.com/IBM/platform-services-go-sdk v0.94.0 - github.com/IBM/vpc-go-sdk v0.76.2 + github.com/IBM/vpc-go-sdk v0.78.1 github.com/blang/semver/v4 v4.0.0 github.com/coreos/ignition/v2 v2.25.1 github.com/go-logr/logr v1.4.3 diff --git a/go.sum b/go.sum index 6c7bbc2b8..1d89d425e 100644 --- a/go.sum +++ b/go.sum @@ -18,8 +18,8 @@ github.com/IBM/networking-go-sdk v0.51.15 h1:JEljJvjUYeSL5F091sI3kZzD9wZYDWsnnKJ github.com/IBM/networking-go-sdk v0.51.15/go.mod h1:TAXWyBUk3C3R7aS1m84EfKdnDcBMZMAClwLfDj/SYZc= github.com/IBM/platform-services-go-sdk v0.94.0 h1:Uj4Gsin5jRb+QYZIHOSl6gzKHTD9JLHsKwfugXdyDYk= github.com/IBM/platform-services-go-sdk v0.94.0/go.mod h1:KAnBhxKaYsu9It2aVXV6oCPEj78imvTs2qSG0ScZKpM= -github.com/IBM/vpc-go-sdk v0.76.2 h1:bZ6aHA1X69Ekn9rxd5XyjxuV9dwEneamEPYojDPHZdA= -github.com/IBM/vpc-go-sdk v0.76.2/go.mod h1:hhgE1EQZRq1Cngdh4A6+LLUaA0kKWW/rgfHpISM+AKg= +github.com/IBM/vpc-go-sdk v0.78.1 h1:vzc1GIoTYZsQCoDWpvS5Ah13qfBfN7wWgTGnHhpBg0M= +github.com/IBM/vpc-go-sdk v0.78.1/go.mod h1:85bJ/0FS7vYAifHdZvlnXypf8pQSmuf9kxReDDI5ZdY= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=