Skip to content

Commit

Permalink
Security group and Security group rules validation
Browse files Browse the repository at this point in the history
Add/Update Validations and validations tests to SecurityGroup and SecurityGroupRule
  • Loading branch information
itzikb-redhat committed Jan 8, 2025
1 parent 7625aa3 commit d6864c2
Show file tree
Hide file tree
Showing 6 changed files with 438 additions and 44 deletions.
72 changes: 60 additions & 12 deletions api/v1alpha1/securitygroup_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,37 +26,85 @@ type RuleDirection string
// +kubebuilder:validation:MaxLength:=16
type Protocol string

const (
ProtocolANY Protocol = "any"
ProtocolAH Protocol = "ah"
ProtocolDCCP Protocol = "dccp"
ProtocolEGP Protocol = "egp"
ProtocolESP Protocol = "esp"
ProtocolGRE Protocol = "gre"
ProtocolICMP Protocol = "icmp"
ProtocolICMPV6 Protocol = "icmpv6"
ProtocolIGMP Protocol = "igmp"
ProtocolIPIP Protocol = "ipip"
ProtocolIPV6ENCAP Protocol = "ipv6-encap"
ProtocolIPV6FRAG Protocol = "ipv6-frag"
ProtocolIPV6ICMP Protocol = "ipv6-icmp"
ProtocolIPV6NONXT Protocol = "ipv6-nonxt"
ProtocolIPV6OPTS Protocol = "ipv6-opts"
ProtocolIPV6ROUTE Protocol = "ipv6-route"
ProtocolOSPF Protocol = "ospf"
ProtocolPGM Protocol = "pgm"
ProtocolRSVP Protocol = "rsvp"
ProtocolSCTP Protocol = "sctp"
ProtocolTCP Protocol = "tcp"
ProtocolUDP Protocol = "udp"
ProtocolUDPLITE Protocol = "udplite"
ProtocolVRRP Protocol = "vrrp"
)

// +kubebuilder:validation:Enum:=IPv4;IPv6
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=16
// +kubebuilder:validation:MaxLength:=4
type Ethertype string

const (
EthertypeIPv4 Ethertype = "IPv4"
EthertypeIPv6 Ethertype = "IPv6"
)

// SecurityGroupRule defines a Security Group rule
// +kubebuilder:validation:MinProperties:=1
// +kubebuilder:validation:XValidation:rule="has(self.portRangeMin) == has(self.portRangeMax)",message="PortRangeMin and PortRangeMax should exist together"
// +kubebuilder:validation:XValidation:rule="(!has(self.portRangeMin) || !has(self.portRangeMax))|| (self.portRangeMin <= self.portRangeMax)",message="PortRangeMax should be equal or greater than PortRangeMin"
// +kubebuilder:validation:XValidation:rule="!(self.protocol == 'icmp' || self.protocol == 'icmpv6') || !has(self.portRangeMin)|| (self.portRangeMin >= 0 && self.portRangeMin <= 255)",message="When protocol is ICMP or ICMPv6 PortRangeMin should be between 0 and 255"
// +kubebuilder:validation:XValidation:rule="!(self.protocol == 'icmp' || self.protocol == 'icmpv6') || !has(self.portRangeMax)|| (self.portRangeMax >= 0 && self.portRangeMax <= 255)",message="When protocol is ICMP or ICMPv6 PortRangeMax should be between 0 and 255"

// +kubebuilder:validation:XValidation:rule="!has(self.remoteIPPrefix) || (isCIDR(self.remoteIPPrefix) && cidr(self.remoteIPPrefix).ip().family() == 4 && self.ethertype == 'IPv4') || (isCIDR(self.remoteIPPrefix) && cidr(self.remoteIPPrefix).ip().family() == 6 && self.ethertype == 'IPv6')",message="RemoteIPPrefix should be a valid CIDR and match the Ethertype"
type SecurityGroupRule struct {
// Description of the existing resource
// +optional

Description *OpenStackDescription `json:"description,omitempty"`

// Direction represents the direction in which the security group rule
// is applied. Can be ingress or egress.
// +optional
Direction *RuleDirection `json:"direction,omitempty"`

// RemoteAddressGroupId (Not in gophercloud)

// RemoteIPPrefix
// RemoteIPPrefix is an IP address block. Should match the Ethertype (IPv4 or IPv6)
// +optional
RemoteIPPrefix *CIDR `json:"remoteIPPrefix,omitempty"`

// Protocol is the IP protocol can be represented by a string, an
// integer, or null
Protocol *Protocol `json:"protocol,omitempty"`
// Protocol is the IP protocol can be represented by a string or an
// integer represented as a string.
// +required
Protocol Protocol `json:"protocol,omitempty"`

// EtherType must be IPv4 or IPv6, and addresses represented in CIDR
// Ethertype must be IPv4 or IPv6, and addresses represented in CIDR
// must match the ingress or egress rules.
Ethertype *Ethertype `json:"ethertype,omitempty"`

PortRangeMin *int32 `json:"portRangeMin,omitempty"`
PortRangeMax *int32 `json:"portRangeMax,omitempty"`
// +kubebuilder:validation:Required
Ethertype *Ethertype `json:"ethertype"`
// If the protocol is [tcp, udp, dccp sctp,udplite] this value must be less than
// or equal to the PortRangeMax attribute value.
// If the protocol is ICMP, this value must be an ICMP code
// +optional
PortRangeMin *uint16 `json:"portRangeMin,omitempty"`
// If the protocol is [tcp, udp, dccp sctp,udplite] this value must be greater than
// or equal to the PortRangeMin attribute value.
// If the protocol is ICMP, this value must be an ICMP type
// +optional
PortRangeMax *uint16 `json:"portRangeMax,omitempty"`
}

type SecurityGroupRuleStatus struct {
Expand Down
9 changes: 2 additions & 7 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 13 additions & 12 deletions cmd/models-schema/zz_generated.openapi.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 39 additions & 9 deletions config/crd/bases/openstack.k-orc.cloud_securitygroups.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,9 @@ spec:
description: Rules is a list of security group rules belonging
to this SG.
items:
description: SecurityGroupRule defines a Security Group rule
minProperties: 1
properties:
description:
description: Description of the existing resource
maxLength: 1024
minLength: 1
type: string
Expand All @@ -250,35 +248,67 @@ spec:
type: string
ethertype:
description: |-
EtherType must be IPv4 or IPv6, and addresses represented in CIDR
Ethertype must be IPv4 or IPv6, and addresses represented in CIDR
must match the ingress or egress rules.
enum:
- IPv4
- IPv6
maxLength: 16
maxLength: 4
minLength: 1
type: string
portRangeMax:
format: int32
description: |-
If the protocol is [tcp, udp, dccp sctp,udplite] this value must be greater than
or equal to the PortRangeMin attribute value.
If the protocol is ICMP, this value must be an ICMP type
type: integer
portRangeMin:
format: int32
description: |-
If the protocol is [tcp, udp, dccp sctp,udplite] this value must be less than
or equal to the PortRangeMax attribute value.
If the protocol is ICMP, this value must be an ICMP code
type: integer
protocol:
description: |-
Protocol is the IP protocol can be represented by a string, an
integer, or null
Protocol is the IP protocol can be represented by a string or an
integer represented as a string.
maxLength: 16
minLength: 1
pattern: \b([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\b|any|ah|dccp|egp|esp|gre|icmp|icmpv6|igmp|ipip|ipv6-encap|ipv6-frag|ipv6-icmp|ipv6-nonxt|ipv6-opts|ipv6-route|ospf|pgm|rsvp|sctp|tcp|udp|udplite|vrrp
type: string
remoteIPPrefix:
description: RemoteIPPrefix
description: RemoteIPPrefix is an IP address block. Should
match the Ethertype (IPv4 or IPv6)
format: cidr
maxLength: 49
minLength: 1
type: string
required:
- ethertype
- protocol
type: object
x-kubernetes-validations:
- message: PortRangeMin and PortRangeMax should exist together
rule: has(self.portRangeMin) == has(self.portRangeMax)
- message: PortRangeMax should be equal or greater than PortRangeMin
rule: (!has(self.portRangeMin) || !has(self.portRangeMax))||
(self.portRangeMin <= self.portRangeMax)
- message: When protocol is ICMP or ICMPv6 PortRangeMin should
be between 0 and 255
rule: '!(self.protocol == ''icmp'' || self.protocol == ''icmpv6'')
|| !has(self.portRangeMin)|| (self.portRangeMin >= 0 &&
self.portRangeMin <= 255)'
- message: When protocol is ICMP or ICMPv6 PortRangeMax should
be between 0 and 255
rule: '!(self.protocol == ''icmp'' || self.protocol == ''icmpv6'')
|| !has(self.portRangeMax)|| (self.portRangeMax >= 0 &&
self.portRangeMax <= 255)'
- message: RemoteIPPrefix should be a valid CIDR and match the
Ethertype
rule: '!has(self.remoteIPPrefix) || (isCIDR(self.remoteIPPrefix)
&& cidr(self.remoteIPPrefix).ip().family() == 4 && self.ethertype
== ''IPv4'') || (isCIDR(self.remoteIPPrefix) && cidr(self.remoteIPPrefix).ip().family()
== 6 && self.ethertype == ''IPv6'')'
maxItems: 256
type: array
x-kubernetes-list-type: atomic
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit d6864c2

Please sign in to comment.