Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/v1beta1/awscluster_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func (src *AWSCluster) ConvertTo(dstRaw conversion.Hub) error {
}

dst.Spec.NetworkSpec.AdditionalControlPlaneIngressRules = restored.Spec.NetworkSpec.AdditionalControlPlaneIngressRules
dst.Spec.NetworkSpec.AdditionalNodeIngressRules = restored.Spec.NetworkSpec.AdditionalNodeIngressRules
dst.Spec.NetworkSpec.NodePortIngressRuleCidrBlocks = restored.Spec.NetworkSpec.NodePortIngressRuleCidrBlocks

if restored.Spec.NetworkSpec.VPC.IPAMPool != nil {
Expand Down
1 change: 1 addition & 0 deletions api/v1beta1/zz_generated.conversion.go

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

39 changes: 17 additions & 22 deletions api/v1beta2/awscluster_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,8 @@ func (r *AWSCluster) validateNetwork() field.ErrorList {
allErrs = append(allErrs, field.Invalid(field.NewPath("ipamPool"), r.Spec.NetworkSpec.VPC.IPAMPool, "ipamPool must have either id or name"))
}

for _, rule := range r.Spec.NetworkSpec.AdditionalControlPlaneIngressRules {
allErrs = append(allErrs, r.validateIngressRule(rule)...)
}
allErrs = append(allErrs, r.validateIngressRules(field.NewPath("spec", "network", "additionalControlPlaneIngressRules"), r.Spec.NetworkSpec.AdditionalControlPlaneIngressRules)...)
allErrs = append(allErrs, r.validateIngressRules(field.NewPath("spec", "network", "additionalNodeIngressRules"), r.Spec.NetworkSpec.AdditionalNodeIngressRules)...)

for cidrBlockIndex, cidrBlock := range r.Spec.NetworkSpec.NodePortIngressRuleCidrBlocks {
if _, _, err := net.ParseCIDR(cidrBlock); err != nil {
Expand Down Expand Up @@ -326,18 +325,11 @@ func (r *AWSCluster) validateControlPlaneLBs() field.ErrorList {

// Additional listeners are only supported for NLBs.
// Validate the control plane load balancers.
loadBalancers := []*AWSLoadBalancerSpec{
r.Spec.ControlPlaneLoadBalancer,
r.Spec.SecondaryControlPlaneLoadBalancer,
if r.Spec.ControlPlaneLoadBalancer != nil {
allErrs = append(allErrs, r.validateIngressRules(field.NewPath("spec", "controlPlaneLoadBalancer", "ingressRules"), r.Spec.ControlPlaneLoadBalancer.IngressRules)...)
}
for _, cp := range loadBalancers {
if cp == nil {
continue
}

for _, rule := range cp.IngressRules {
allErrs = append(allErrs, r.validateIngressRule(rule)...)
}
if r.Spec.SecondaryControlPlaneLoadBalancer != nil {
allErrs = append(allErrs, r.validateIngressRules(field.NewPath("spec", "secondaryControlPlaneLoadBalancer", "ingressRules"), r.Spec.SecondaryControlPlaneLoadBalancer.IngressRules)...)
}

if r.Spec.ControlPlaneLoadBalancer.LoadBalancerType == LoadBalancerTypeDisabled {
Expand Down Expand Up @@ -381,15 +373,18 @@ func (r *AWSCluster) validateControlPlaneLBs() field.ErrorList {
return allErrs
}

func (r *AWSCluster) validateIngressRule(rule IngressRule) field.ErrorList {
func (r *AWSCluster) validateIngressRules(path *field.Path, rules []IngressRule) field.ErrorList {
var allErrs field.ErrorList
if rule.NatGatewaysIPsSource {
if rule.CidrBlocks != nil || rule.IPv6CidrBlocks != nil || rule.SourceSecurityGroupIDs != nil || rule.SourceSecurityGroupRoles != nil {
allErrs = append(allErrs, field.Invalid(field.NewPath("additionalControlPlaneIngressRules"), r.Spec.NetworkSpec.AdditionalControlPlaneIngressRules, "CIDR blocks and security group IDs or security group roles cannot be used together"))
}
} else {
if (rule.CidrBlocks != nil || rule.IPv6CidrBlocks != nil) && (rule.SourceSecurityGroupIDs != nil || rule.SourceSecurityGroupRoles != nil) {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "controlPlaneLoadBalancer", "ingressRules"), r.Spec.ControlPlaneLoadBalancer.IngressRules, "CIDR blocks and security group IDs or security group roles cannot be used together"))
for ruleIndex, rule := range rules {
rulePath := path.Index(ruleIndex)
if rule.NatGatewaysIPsSource {
if rule.CidrBlocks != nil || rule.IPv6CidrBlocks != nil || rule.SourceSecurityGroupIDs != nil || rule.SourceSecurityGroupRoles != nil {
allErrs = append(allErrs, field.Invalid(rulePath, rules, "natGatewaysIPsSource cannot be used together with CIDR blocks, security group IDs or security group roles"))
}
} else {
if (rule.CidrBlocks != nil || rule.IPv6CidrBlocks != nil) && (rule.SourceSecurityGroupIDs != nil || rule.SourceSecurityGroupRoles != nil) {
allErrs = append(allErrs, field.Invalid(rulePath, rules, "CIDR blocks and security group IDs or security group roles cannot be used together"))
}
}
}
return allErrs
Expand Down
85 changes: 85 additions & 0 deletions api/v1beta2/awscluster_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,91 @@ func TestAWSClusterValidateCreate(t *testing.T) {
},
wantErr: false,
},
{
name: "accepts node ingress rules with source security group id and role",
cluster: &AWSCluster{
Spec: AWSClusterSpec{
NetworkSpec: NetworkSpec{
AdditionalNodeIngressRules: []IngressRule{
{
Protocol: SecurityGroupProtocolTCP,
SourceSecurityGroupIDs: []string{"test"},
SourceSecurityGroupRoles: []SecurityGroupRole{SecurityGroupBastion},
},
},
},
},
},
wantErr: false,
},
{
name: "rejects node ingress rules with cidr block and source security group id",
cluster: &AWSCluster{
Spec: AWSClusterSpec{
NetworkSpec: NetworkSpec{
AdditionalNodeIngressRules: []IngressRule{
{
Protocol: SecurityGroupProtocolTCP,
CidrBlocks: []string{"test"},
SourceSecurityGroupIDs: []string{"test"},
},
},
},
},
},
wantErr: true,
},
{
name: "rejects node ingress rules with cidr block and source security group id and role",
cluster: &AWSCluster{
Spec: AWSClusterSpec{
NetworkSpec: NetworkSpec{
AdditionalNodeIngressRules: []IngressRule{
{
Protocol: SecurityGroupProtocolTCP,
IPv6CidrBlocks: []string{"test"},
SourceSecurityGroupIDs: []string{"test"},
SourceSecurityGroupRoles: []SecurityGroupRole{SecurityGroupBastion},
},
},
},
},
},
wantErr: true,
},
{
name: "accepts node ingress rules with cidr block",
cluster: &AWSCluster{
Spec: AWSClusterSpec{
NetworkSpec: NetworkSpec{
AdditionalNodeIngressRules: []IngressRule{
{
Protocol: SecurityGroupProtocolTCP,
CidrBlocks: []string{"test"},
},
},
},
},
},
wantErr: false,
},
{
name: "accepts node ingress rules with source security group id and role",
cluster: &AWSCluster{
Spec: AWSClusterSpec{
NetworkSpec: NetworkSpec{
AdditionalNodeIngressRules: []IngressRule{
{
Protocol: SecurityGroupProtocolTCP,
SourceSecurityGroupIDs: []string{"test"},
SourceSecurityGroupRoles: []SecurityGroupRole{SecurityGroupBastion},
},
},
},
},
},
wantErr: false,
},
{
name: "accepts cidrBlock for default node port ingress rule",
cluster: &AWSCluster{
Expand Down
4 changes: 4 additions & 0 deletions api/v1beta2/network_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,10 @@ type NetworkSpec struct {
// +optional
AdditionalControlPlaneIngressRules []IngressRule `json:"additionalControlPlaneIngressRules,omitempty"`

// AdditionalNodeIngressRules is an optional set of ingress rules to add to every node
// +optional
AdditionalNodeIngressRules []IngressRule `json:"additionalNodeIngressRules,omitempty"`

// NodePortIngressRuleCidrBlocks is an optional set of CIDR blocks to allow traffic to nodes' NodePort services.
// If none are specified here, all IPs are allowed to connect.
// +optional
Expand Down
7 changes: 7 additions & 0 deletions api/v1beta2/zz_generated.deepcopy.go

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

Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,83 @@ spec:
- toPort
type: object
type: array
additionalNodeIngressRules:
description: AdditionalNodeIngressRules is an optional set of
ingress rules to add to every node
items:
description: IngressRule defines an AWS ingress rule for security
groups.
properties:
cidrBlocks:
description: List of CIDR blocks to allow access from. Cannot
be specified with SourceSecurityGroupID.
items:
type: string
type: array
description:
description: Description provides extended information about
the ingress rule.
type: string
fromPort:
description: FromPort is the start of port range.
format: int64
type: integer
ipv6CidrBlocks:
description: List of IPv6 CIDR blocks to allow access from.
Cannot be specified with SourceSecurityGroupID.
items:
type: string
type: array
natGatewaysIPsSource:
description: NatGatewaysIPsSource use the NAT gateways IPs
as the source for the ingress rule.
type: boolean
protocol:
description: Protocol is the protocol for the ingress rule.
Accepted values are "-1" (all), "4" (IP in IP),"tcp",
"udp", "icmp", and "58" (ICMPv6), "50" (ESP).
enum:
- "-1"
- "4"
- tcp
- udp
- icmp
- "58"
- "50"
type: string
sourceSecurityGroupIds:
description: The security group id to allow access from.
Cannot be specified with CidrBlocks.
items:
type: string
type: array
sourceSecurityGroupRoles:
description: |-
The security group role to allow access from. Cannot be specified with CidrBlocks.
The field will be combined with source security group IDs if specified.
items:
description: SecurityGroupRole defines the unique role
of a security group.
enum:
- bastion
- node
- controlplane
- apiserver-lb
- lb
- node-eks-additional
type: string
type: array
toPort:
description: ToPort is the end of port range.
format: int64
type: integer
required:
- description
- fromPort
- protocol
- toPort
type: object
type: array
cni:
description: CNI configuration
properties:
Expand Down Expand Up @@ -2465,6 +2542,83 @@ spec:
- toPort
type: object
type: array
additionalNodeIngressRules:
description: AdditionalNodeIngressRules is an optional set of
ingress rules to add to every node
items:
description: IngressRule defines an AWS ingress rule for security
groups.
properties:
cidrBlocks:
description: List of CIDR blocks to allow access from. Cannot
be specified with SourceSecurityGroupID.
items:
type: string
type: array
description:
description: Description provides extended information about
the ingress rule.
type: string
fromPort:
description: FromPort is the start of port range.
format: int64
type: integer
ipv6CidrBlocks:
description: List of IPv6 CIDR blocks to allow access from.
Cannot be specified with SourceSecurityGroupID.
items:
type: string
type: array
natGatewaysIPsSource:
description: NatGatewaysIPsSource use the NAT gateways IPs
as the source for the ingress rule.
type: boolean
protocol:
description: Protocol is the protocol for the ingress rule.
Accepted values are "-1" (all), "4" (IP in IP),"tcp",
"udp", "icmp", and "58" (ICMPv6), "50" (ESP).
enum:
- "-1"
- "4"
- tcp
- udp
- icmp
- "58"
- "50"
type: string
sourceSecurityGroupIds:
description: The security group id to allow access from.
Cannot be specified with CidrBlocks.
items:
type: string
type: array
sourceSecurityGroupRoles:
description: |-
The security group role to allow access from. Cannot be specified with CidrBlocks.
The field will be combined with source security group IDs if specified.
items:
description: SecurityGroupRole defines the unique role
of a security group.
enum:
- bastion
- node
- controlplane
- apiserver-lb
- lb
- node-eks-additional
type: string
type: array
toPort:
description: ToPort is the end of port range.
format: int64
type: integer
required:
- description
- fromPort
- protocol
- toPort
type: object
type: array
cni:
description: CNI configuration
properties:
Expand Down
Loading
Loading