diff --git a/api/v1alpha3/awscluster_conversion.go b/api/v1alpha3/awscluster_conversion.go index 0345229b81..944d894d97 100644 --- a/api/v1alpha3/awscluster_conversion.go +++ b/api/v1alpha3/awscluster_conversion.go @@ -136,3 +136,7 @@ func Convert_v1beta1_AWSClusterSpec_To_v1alpha3_AWSClusterSpec(in *infrav1.AWSCl func Convert_v1beta1_AWSClusterStatus_To_v1alpha3_AWSClusterStatus(in *infrav1.AWSClusterStatus, out *AWSClusterStatus, s apiconversion.Scope) error { return autoConvert_v1beta1_AWSClusterStatus_To_v1alpha3_AWSClusterStatus(in, out, s) } + +func Convert_v1beta1_IngressRule_To_v1alpha3_IngressRule(in *infrav1.IngressRule, out *IngressRule, s apiconversion.Scope) error { + return autoConvert_v1beta1_IngressRule_To_v1alpha3_IngressRule(in, out, s) +} diff --git a/api/v1alpha3/zz_generated.conversion.go b/api/v1alpha3/zz_generated.conversion.go index 52546ffc7f..2db2b576fe 100644 --- a/api/v1alpha3/zz_generated.conversion.go +++ b/api/v1alpha3/zz_generated.conversion.go @@ -1051,6 +1051,7 @@ func autoConvert_v1beta1_AWSLoadBalancerSpec_To_v1alpha3_AWSLoadBalancerSpec(in out.Subnets = *(*[]string)(unsafe.Pointer(&in.Subnets)) // WARNING: in.HealthCheckProtocol requires manual conversion: does not exist in peer-type out.AdditionalSecurityGroups = *(*[]string)(unsafe.Pointer(&in.AdditionalSecurityGroups)) + // WARNING: in.IngressRules requires manual conversion: does not exist in peer-type return nil } @@ -1778,14 +1779,10 @@ func autoConvert_v1beta1_IngressRule_To_v1alpha3_IngressRule(in *v1beta1.Ingress out.ToPort = in.ToPort out.CidrBlocks = *(*[]string)(unsafe.Pointer(&in.CidrBlocks)) out.SourceSecurityGroupIDs = *(*[]string)(unsafe.Pointer(&in.SourceSecurityGroupIDs)) + // WARNING: in.SourceSecurityGroupRoles requires manual conversion: does not exist in peer-type return nil } -// Convert_v1beta1_IngressRule_To_v1alpha3_IngressRule is an autogenerated conversion function. -func Convert_v1beta1_IngressRule_To_v1alpha3_IngressRule(in *v1beta1.IngressRule, out *IngressRule, s conversion.Scope) error { - return autoConvert_v1beta1_IngressRule_To_v1alpha3_IngressRule(in, out, s) -} - func autoConvert_v1alpha3_Instance_To_v1beta1_Instance(in *Instance, out *v1beta1.Instance, s conversion.Scope) error { out.ID = in.ID out.State = v1beta1.InstanceState(in.State) @@ -1951,7 +1948,17 @@ func Convert_v1beta1_RouteTable_To_v1alpha3_RouteTable(in *v1beta1.RouteTable, o func autoConvert_v1alpha3_SecurityGroup_To_v1beta1_SecurityGroup(in *SecurityGroup, out *v1beta1.SecurityGroup, s conversion.Scope) error { out.ID = in.ID out.Name = in.Name - out.IngressRules = *(*v1beta1.IngressRules)(unsafe.Pointer(&in.IngressRules)) + if in.IngressRules != nil { + in, out := &in.IngressRules, &out.IngressRules + *out = make(v1beta1.IngressRules, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_IngressRule_To_v1beta1_IngressRule(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.IngressRules = nil + } out.Tags = *(*v1beta1.Tags)(unsafe.Pointer(&in.Tags)) return nil } @@ -1964,7 +1971,17 @@ func Convert_v1alpha3_SecurityGroup_To_v1beta1_SecurityGroup(in *SecurityGroup, func autoConvert_v1beta1_SecurityGroup_To_v1alpha3_SecurityGroup(in *v1beta1.SecurityGroup, out *SecurityGroup, s conversion.Scope) error { out.ID = in.ID out.Name = in.Name - out.IngressRules = *(*IngressRules)(unsafe.Pointer(&in.IngressRules)) + if in.IngressRules != nil { + in, out := &in.IngressRules, &out.IngressRules + *out = make(IngressRules, len(*in)) + for i := range *in { + if err := Convert_v1beta1_IngressRule_To_v1alpha3_IngressRule(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.IngressRules = nil + } out.Tags = *(*Tags)(unsafe.Pointer(&in.Tags)) return nil } diff --git a/api/v1alpha4/awscluster_conversion.go b/api/v1alpha4/awscluster_conversion.go index 0dbb8b55e7..1f3ddef023 100644 --- a/api/v1alpha4/awscluster_conversion.go +++ b/api/v1alpha4/awscluster_conversion.go @@ -44,6 +44,9 @@ func (src *AWSCluster) ConvertTo(dstRaw conversion.Hub) error { } restoreControlPlaneLoadBalancer(restored.Spec.ControlPlaneLoadBalancer, dst.Spec.ControlPlaneLoadBalancer) } + for role, sg := range restored.Status.Network.SecurityGroups { + dst.Status.Network.SecurityGroups[role] = sg + } dst.Spec.S3Bucket = restored.Spec.S3Bucket @@ -55,6 +58,7 @@ func (src *AWSCluster) ConvertTo(dstRaw conversion.Hub) error { func restoreControlPlaneLoadBalancer(restored, dst *infrav1.AWSLoadBalancerSpec) { dst.Name = restored.Name dst.HealthCheckProtocol = restored.HealthCheckProtocol + dst.IngressRules = restored.IngressRules } // ConvertFrom converts the v1beta1 AWSCluster receiver to a v1alpha4 AWSCluster. diff --git a/api/v1alpha4/conversion.go b/api/v1alpha4/conversion.go index cc14f0e882..d755d39ff8 100644 --- a/api/v1alpha4/conversion.go +++ b/api/v1alpha4/conversion.go @@ -25,3 +25,7 @@ import ( func Convert_v1beta1_AWSClusterSpec_To_v1alpha4_AWSClusterSpec(in *v1beta1.AWSClusterSpec, out *AWSClusterSpec, s conversion.Scope) error { return autoConvert_v1beta1_AWSClusterSpec_To_v1alpha4_AWSClusterSpec(in, out, s) } + +func Convert_v1beta1_IngressRule_To_v1alpha4_IngressRule(in *v1beta1.IngressRule, out *IngressRule, s conversion.Scope) error { + return autoConvert_v1beta1_IngressRule_To_v1alpha4_IngressRule(in, out, s) +} diff --git a/api/v1alpha4/zz_generated.conversion.go b/api/v1alpha4/zz_generated.conversion.go index 854658ccaa..a388cd9acf 100644 --- a/api/v1alpha4/zz_generated.conversion.go +++ b/api/v1alpha4/zz_generated.conversion.go @@ -1214,6 +1214,7 @@ func autoConvert_v1beta1_AWSLoadBalancerSpec_To_v1alpha4_AWSLoadBalancerSpec(in out.Subnets = *(*[]string)(unsafe.Pointer(&in.Subnets)) // WARNING: in.HealthCheckProtocol requires manual conversion: does not exist in peer-type out.AdditionalSecurityGroups = *(*[]string)(unsafe.Pointer(&in.AdditionalSecurityGroups)) + // WARNING: in.IngressRules requires manual conversion: does not exist in peer-type return nil } @@ -1905,14 +1906,10 @@ func autoConvert_v1beta1_IngressRule_To_v1alpha4_IngressRule(in *v1beta1.Ingress out.ToPort = in.ToPort out.CidrBlocks = *(*[]string)(unsafe.Pointer(&in.CidrBlocks)) out.SourceSecurityGroupIDs = *(*[]string)(unsafe.Pointer(&in.SourceSecurityGroupIDs)) + // WARNING: in.SourceSecurityGroupRoles requires manual conversion: does not exist in peer-type return nil } -// Convert_v1beta1_IngressRule_To_v1alpha4_IngressRule is an autogenerated conversion function. -func Convert_v1beta1_IngressRule_To_v1alpha4_IngressRule(in *v1beta1.IngressRule, out *IngressRule, s conversion.Scope) error { - return autoConvert_v1beta1_IngressRule_To_v1alpha4_IngressRule(in, out, s) -} - func autoConvert_v1alpha4_Instance_To_v1beta1_Instance(in *Instance, out *v1beta1.Instance, s conversion.Scope) error { out.ID = in.ID out.State = v1beta1.InstanceState(in.State) @@ -2026,7 +2023,19 @@ func Convert_v1beta1_NetworkSpec_To_v1alpha4_NetworkSpec(in *v1beta1.NetworkSpec } func autoConvert_v1alpha4_NetworkStatus_To_v1beta1_NetworkStatus(in *NetworkStatus, out *v1beta1.NetworkStatus, s conversion.Scope) error { - out.SecurityGroups = *(*map[v1beta1.SecurityGroupRole]v1beta1.SecurityGroup)(unsafe.Pointer(&in.SecurityGroups)) + if in.SecurityGroups != nil { + in, out := &in.SecurityGroups, &out.SecurityGroups + *out = make(map[v1beta1.SecurityGroupRole]v1beta1.SecurityGroup, len(*in)) + for key, val := range *in { + newVal := new(v1beta1.SecurityGroup) + if err := Convert_v1alpha4_SecurityGroup_To_v1beta1_SecurityGroup(&val, newVal, s); err != nil { + return err + } + (*out)[v1beta1.SecurityGroupRole(key)] = *newVal + } + } else { + out.SecurityGroups = nil + } if err := Convert_v1alpha4_ClassicELB_To_v1beta1_ClassicELB(&in.APIServerELB, &out.APIServerELB, s); err != nil { return err } @@ -2039,7 +2048,19 @@ func Convert_v1alpha4_NetworkStatus_To_v1beta1_NetworkStatus(in *NetworkStatus, } func autoConvert_v1beta1_NetworkStatus_To_v1alpha4_NetworkStatus(in *v1beta1.NetworkStatus, out *NetworkStatus, s conversion.Scope) error { - out.SecurityGroups = *(*map[SecurityGroupRole]SecurityGroup)(unsafe.Pointer(&in.SecurityGroups)) + if in.SecurityGroups != nil { + in, out := &in.SecurityGroups, &out.SecurityGroups + *out = make(map[SecurityGroupRole]SecurityGroup, len(*in)) + for key, val := range *in { + newVal := new(SecurityGroup) + if err := Convert_v1beta1_SecurityGroup_To_v1alpha4_SecurityGroup(&val, newVal, s); err != nil { + return err + } + (*out)[SecurityGroupRole(key)] = *newVal + } + } else { + out.SecurityGroups = nil + } if err := Convert_v1beta1_ClassicELB_To_v1alpha4_ClassicELB(&in.APIServerELB, &out.APIServerELB, s); err != nil { return err } @@ -2074,7 +2095,17 @@ func Convert_v1beta1_RouteTable_To_v1alpha4_RouteTable(in *v1beta1.RouteTable, o func autoConvert_v1alpha4_SecurityGroup_To_v1beta1_SecurityGroup(in *SecurityGroup, out *v1beta1.SecurityGroup, s conversion.Scope) error { out.ID = in.ID out.Name = in.Name - out.IngressRules = *(*v1beta1.IngressRules)(unsafe.Pointer(&in.IngressRules)) + if in.IngressRules != nil { + in, out := &in.IngressRules, &out.IngressRules + *out = make(v1beta1.IngressRules, len(*in)) + for i := range *in { + if err := Convert_v1alpha4_IngressRule_To_v1beta1_IngressRule(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.IngressRules = nil + } out.Tags = *(*v1beta1.Tags)(unsafe.Pointer(&in.Tags)) return nil } @@ -2087,7 +2118,17 @@ func Convert_v1alpha4_SecurityGroup_To_v1beta1_SecurityGroup(in *SecurityGroup, func autoConvert_v1beta1_SecurityGroup_To_v1alpha4_SecurityGroup(in *v1beta1.SecurityGroup, out *SecurityGroup, s conversion.Scope) error { out.ID = in.ID out.Name = in.Name - out.IngressRules = *(*IngressRules)(unsafe.Pointer(&in.IngressRules)) + if in.IngressRules != nil { + in, out := &in.IngressRules, &out.IngressRules + *out = make(IngressRules, len(*in)) + for i := range *in { + if err := Convert_v1beta1_IngressRule_To_v1alpha4_IngressRule(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.IngressRules = nil + } out.Tags = *(*Tags)(unsafe.Pointer(&in.Tags)) return nil } diff --git a/api/v1beta1/awscluster_types.go b/api/v1beta1/awscluster_types.go index dde43edbdc..8e24efe298 100644 --- a/api/v1beta1/awscluster_types.go +++ b/api/v1beta1/awscluster_types.go @@ -200,6 +200,11 @@ type AWSLoadBalancerSpec struct { // This is optional - if not provided new security groups will be created for the load balancer // +optional AdditionalSecurityGroups []string `json:"additionalSecurityGroups,omitempty"` + + // IngressRules sets the additional ingress rules for the control plane load balancer. If no source security group ids are specified, the + // default control plane security group will be used. + // +optional + IngressRules []IngressRule `json:"ingressRules,omitempty"` } // AWSClusterStatus defines the observed state of AWSCluster. diff --git a/api/v1beta1/awscluster_webhook.go b/api/v1beta1/awscluster_webhook.go index 5fe59063ad..d17f93eeb3 100644 --- a/api/v1beta1/awscluster_webhook.go +++ b/api/v1beta1/awscluster_webhook.go @@ -56,6 +56,7 @@ func (r *AWSCluster) ValidateCreate() error { allErrs = append(allErrs, r.validateSSHKeyName()...) allErrs = append(allErrs, r.Spec.AdditionalTags.Validate()...) allErrs = append(allErrs, r.Spec.S3Bucket.Validate()...) + allErrs = append(allErrs, r.ingressRules()...) return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs) } @@ -178,3 +179,19 @@ func (r *AWSCluster) Default() { func (r *AWSCluster) validateSSHKeyName() field.ErrorList { return validateSSHKeyName(r.Spec.SSHKeyName) } + +func (r *AWSCluster) ingressRules() field.ErrorList { + var allErrs field.ErrorList + + if r.Spec.ControlPlaneLoadBalancer == nil { + return allErrs + } + + for _, rule := range r.Spec.ControlPlaneLoadBalancer.IngressRules { + if rule.CidrBlocks != nil && (rule.SourceSecurityGroupIDs != nil || rule.SourceSecurityGroupRoles != nil) { + allErrs = append(allErrs, field.Invalid(field.NewPath("ingressRules"), r.Spec.ControlPlaneLoadBalancer.IngressRules, "CIDR blocks and security group IDs or security group roles cannot be used together")) + } + } + + return allErrs +} diff --git a/api/v1beta1/awscluster_webhook_test.go b/api/v1beta1/awscluster_webhook_test.go index ccf929e344..31e484331b 100644 --- a/api/v1beta1/awscluster_webhook_test.go +++ b/api/v1beta1/awscluster_webhook_test.go @@ -222,6 +222,72 @@ func TestAWSCluster_ValidateCreate(t *testing.T) { }, wantErr: false, }, + { + name: "rejects additional ingress rules with cidr block and source security group id", + cluster: &AWSCluster{ + Spec: AWSClusterSpec{ + ControlPlaneLoadBalancer: &AWSLoadBalancerSpec{ + IngressRules: []IngressRule{ + { + Protocol: SecurityGroupProtocolTCP, + CidrBlocks: []string{"test"}, + SourceSecurityGroupIDs: []string{"test"}, + }, + }, + }, + }, + }, + wantErr: true, + }, + { + name: "accepts additional ingress rules with cidr block", + cluster: &AWSCluster{ + Spec: AWSClusterSpec{ + ControlPlaneLoadBalancer: &AWSLoadBalancerSpec{ + IngressRules: []IngressRule{ + { + Protocol: SecurityGroupProtocolTCP, + CidrBlocks: []string{"test"}, + }, + }, + }, + }, + }, + wantErr: false, + }, + { + name: "accepts additional ingress rules with source security group role", + cluster: &AWSCluster{ + Spec: AWSClusterSpec{ + ControlPlaneLoadBalancer: &AWSLoadBalancerSpec{ + IngressRules: []IngressRule{ + { + Protocol: SecurityGroupProtocolTCP, + SourceSecurityGroupRoles: []SecurityGroupRole{SecurityGroupBastion}, + }, + }, + }, + }, + }, + wantErr: false, + }, + { + name: "accepts additional ingress rules with source security group id and role", + cluster: &AWSCluster{ + Spec: AWSClusterSpec{ + ControlPlaneLoadBalancer: &AWSLoadBalancerSpec{ + IngressRules: []IngressRule{ + { + Protocol: SecurityGroupProtocolTCP, + SourceSecurityGroupIDs: []string{"test"}, + SourceSecurityGroupRoles: []SecurityGroupRole{SecurityGroupBastion}, + }, + }, + }, + }, + }, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/api/v1beta1/network_types.go b/api/v1beta1/network_types.go index adc70f2200..68774ab19d 100644 --- a/api/v1beta1/network_types.go +++ b/api/v1beta1/network_types.go @@ -427,10 +427,15 @@ var ( // IngressRule defines an AWS ingress rule for security groups. type IngressRule struct { - Description string `json:"description"` - Protocol SecurityGroupProtocol `json:"protocol"` - FromPort int64 `json:"fromPort"` - ToPort int64 `json:"toPort"` + // Description provides extended information about the ingress rule. + Description string `json:"description"` + // Protocol is the protocol for the ingress rule. Accepted values are "-1" (all), "4" (IP in IP),"tcp", "udp", "icmp", and "58" (ICMPv6). + // +kubebuilder:validation:Enum="-1";"4";tcp;udp;icmp;"58" + Protocol SecurityGroupProtocol `json:"protocol"` + // FromPort is the start of port range. + FromPort int64 `json:"fromPort"` + // ToPort is the end of port range. + ToPort int64 `json:"toPort"` // List of CIDR blocks to allow access from. Cannot be specified with SourceSecurityGroupID. // +optional @@ -439,6 +444,11 @@ type IngressRule struct { // The security group id to allow access from. Cannot be specified with CidrBlocks. // +optional SourceSecurityGroupIDs []string `json:"sourceSecurityGroupIds,omitempty"` + + // 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. + // +optional + SourceSecurityGroupRoles []SecurityGroupRole `json:"sourceSecurityGroupRoles,omitempty"` } // String returns a string representation of the ingress rule. diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 84b1fa2037..a7cc3f93c7 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -574,6 +574,13 @@ func (in *AWSLoadBalancerSpec) DeepCopyInto(out *AWSLoadBalancerSpec) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.IngressRules != nil { + in, out := &in.IngressRules, &out.IngressRules + *out = make([]IngressRule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSLoadBalancerSpec. @@ -1206,6 +1213,11 @@ func (in *IngressRule) DeepCopyInto(out *IngressRule) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.SourceSecurityGroupRoles != nil { + in, out := &in.SourceSecurityGroupRoles, &out.SourceSecurityGroupRoles + *out = make([]SecurityGroupRole, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressRule. diff --git a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml index 2e9648cc8b..f11f999017 100644 --- a/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml +++ b/config/crd/bases/controlplane.cluster.x-k8s.io_awsmanagedcontrolplanes.yaml @@ -3300,13 +3300,24 @@ spec: 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 protocol: - description: SecurityGroupProtocol defines the protocol - type for a security group rule. + description: Protocol is the protocol for the ingress + rule. Accepted values are "-1" (all), "4" (IP in + IP),"tcp", "udp", "icmp", and "58" (ICMPv6). + enum: + - "-1" + - "4" + - tcp + - udp + - icmp + - "58" type: string sourceSecurityGroupIds: description: The security group id to allow access @@ -3314,7 +3325,18 @@ spec: 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. + type: string + type: array toPort: + description: ToPort is the end of port range. format: int64 type: integer required: diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml index 5aa19f83b2..88b4d284ec 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml @@ -1640,6 +1640,67 @@ spec: description: ControlPlaneLoadBalancer is optional configuration for customizing control plane behavior. properties: + ingressRules: + description: IngressRules sets the additional ingress + rules for the control plane load balancer. If no source security + group ids are specified, the default control plane security + group will be used. + 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 + 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). + enum: + - "-1" + - "4" + - tcp + - udp + - icmp + - "58" + 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. + 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 additionalSecurityGroups: description: AdditionalSecurityGroups sets the security groups used by the load balancer. Expected to be security group IDs @@ -2296,13 +2357,24 @@ spec: 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 protocol: - description: SecurityGroupProtocol defines the protocol - type for a security group rule. + description: Protocol is the protocol for the ingress + rule. Accepted values are "-1" (all), "4" (IP in + IP),"tcp", "udp", "icmp", and "58" (ICMPv6). + enum: + - "-1" + - "4" + - tcp + - udp + - icmp + - "58" type: string sourceSecurityGroupIds: description: The security group id to allow access @@ -2310,7 +2382,18 @@ spec: 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. + type: string + type: array toPort: + description: ToPort is the end of port range. format: int64 type: integer required: diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclustertemplates.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclustertemplates.yaml index bb855142d6..814af7cc9e 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclustertemplates.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_awsclustertemplates.yaml @@ -462,6 +462,68 @@ spec: description: ControlPlaneLoadBalancer is optional configuration for customizing control plane behavior. properties: + ingressRules: + description: IngressRules sets the additional + ingress rules for the control plane load balancer. If + no source security group ids are specified, the default + control plane security group will be used. + 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 + 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). + enum: + - "-1" + - "4" + - tcp + - udp + - icmp + - "58" + 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. + 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 additionalSecurityGroups: description: AdditionalSecurityGroups sets the security groups used by the load balancer. Expected to be security diff --git a/pkg/cloud/scope/managedcontrolplane.go b/pkg/cloud/scope/managedcontrolplane.go index f35cee9557..8b967cc7e4 100644 --- a/pkg/cloud/scope/managedcontrolplane.go +++ b/pkg/cloud/scope/managedcontrolplane.go @@ -303,6 +303,11 @@ func (s *ManagedControlPlaneScope) Bucket() *infrav1.S3Bucket { return nil // no s3 bucket for managed clusters } +// ControlPlaneLoadBalancer returns the AWSLoadBalancerSpec. +func (s *ManagedControlPlaneScope) ControlPlaneLoadBalancer() *infrav1.AWSLoadBalancerSpec { + return nil +} + // AssociateOIDCProvider returns if the cluster should have an OIDC Provider Associated. func (s *ManagedControlPlaneScope) AssociateOIDCProvider() bool { return s.ControlPlane.Spec.AssociateOIDCProvider diff --git a/pkg/cloud/scope/sg.go b/pkg/cloud/scope/sg.go index 6337f0435e..36167a0a2f 100644 --- a/pkg/cloud/scope/sg.go +++ b/pkg/cloud/scope/sg.go @@ -42,4 +42,7 @@ type SGScope interface { // Bastion returns the bastion details for the cluster. Bastion() *infrav1.Bastion + + // ControlPlaneLoadBalancer returns the load balancer settings that are requested. + ControlPlaneLoadBalancer() *infrav1.AWSLoadBalancerSpec } diff --git a/pkg/cloud/services/securitygroup/securitygroups.go b/pkg/cloud/services/securitygroup/securitygroups.go index a3feb3e7dd..178a016adc 100644 --- a/pkg/cloud/services/securitygroup/securitygroups.go +++ b/pkg/cloud/services/securitygroup/securitygroups.go @@ -518,6 +518,20 @@ func (s *Service) getSecurityGroupIngressRules(role infrav1.SecurityGroupRole) ( if s.scope.Bastion().Enabled { rules = append(rules, s.defaultSSHIngressRule(s.scope.SecurityGroups()[infrav1.SecurityGroupBastion].ID)) } + if s.scope.ControlPlaneLoadBalancer() != nil { + ingressRules := s.scope.ControlPlaneLoadBalancer().IngressRules + for i := range ingressRules { + if ingressRules[i].SourceSecurityGroupIDs == nil && ingressRules[i].SourceSecurityGroupRoles == nil { // if the rule doesn't have a source security group, use the control plane security group + ingressRules[i].SourceSecurityGroupIDs = []string{s.scope.SecurityGroups()[infrav1.SecurityGroupControlPlane].ID} + continue + } + + for _, sourceSGRole := range ingressRules[i].SourceSecurityGroupRoles { + ingressRules[i].SourceSecurityGroupIDs = append(ingressRules[i].SourceSecurityGroupIDs, s.scope.SecurityGroups()[sourceSGRole].ID) + } + } + rules = append(rules, s.scope.ControlPlaneLoadBalancer().IngressRules...) + } return append(cniRules, rules...), nil case infrav1.SecurityGroupNode: @@ -553,15 +567,11 @@ func (s *Service) getSecurityGroupIngressRules(role infrav1.SecurityGroupRole) ( } return infrav1.IngressRules{}, nil case infrav1.SecurityGroupAPIServerLB: - return infrav1.IngressRules{ - { - Description: "Kubernetes API", - Protocol: infrav1.SecurityGroupProtocolTCP, - FromPort: int64(s.scope.APIServerPort()), - ToPort: int64(s.scope.APIServerPort()), - CidrBlocks: []string{services.AnyIPv4CidrBlock}, - }, - }, nil + rules := s.getDefaultIngressRulesForControlPlaneLB() + if s.scope.ControlPlaneLoadBalancer() != nil && len(s.scope.ControlPlaneLoadBalancer().IngressRules) > 0 { + rules = s.scope.ControlPlaneLoadBalancer().IngressRules + } + return rules, nil case infrav1.SecurityGroupLB: // We hand this group off to the in-cluster cloud provider, so these rules aren't used return infrav1.IngressRules{}, nil @@ -707,3 +717,27 @@ func ingressRulesFromSDKType(v *ec2.IpPermission) (res infrav1.IngressRules) { return res } + +func (s *Service) getDefaultIngressRulesForControlPlaneLB() infrav1.IngressRules { + //if s.scope.VPC().IsIPv6Enabled() { + // return infrav1.IngressRules{ + // { + // Description: "Kubernetes API IPv6", + // Protocol: infrav1.SecurityGroupProtocolTCP, + // FromPort: int64(s.scope.APIServerPort()), + // ToPort: int64(s.scope.APIServerPort()), + // IPv6CidrBlocks: []string{services.AnyIPv6CidrBlock}, + // }, + // } + //} + + return infrav1.IngressRules{ + { + Description: "Kubernetes API", + Protocol: infrav1.SecurityGroupProtocolTCP, + FromPort: int64(s.scope.APIServerPort()), + ToPort: int64(s.scope.APIServerPort()), + CidrBlocks: []string{services.AnyIPv4CidrBlock}, + }, + } +} diff --git a/pkg/cloud/services/securitygroup/securitygroups_test.go b/pkg/cloud/services/securitygroup/securitygroups_test.go index 05170fab62..50e53d63b8 100644 --- a/pkg/cloud/services/securitygroup/securitygroups_test.go +++ b/pkg/cloud/services/securitygroup/securitygroups_test.go @@ -17,6 +17,7 @@ limitations under the License. package securitygroup import ( + "reflect" "strings" "testing" @@ -401,6 +402,269 @@ func TestControlPlaneSecurityGroupNotOpenToAnyCIDR(t *testing.T) { } } +func TestAdditionalControlPlaneSecurityGroup(t *testing.T) { + scheme := runtime.NewScheme() + _ = infrav1.AddToScheme(scheme) + + testCases := []struct { + name string + controlPlaneLBSpec *infrav1.AWSLoadBalancerSpec + expectedAdditionalIngresRule infrav1.IngressRule + }{ + { + name: "default control plane security group is used", + controlPlaneLBSpec: &infrav1.AWSLoadBalancerSpec{ + IngressRules: []infrav1.IngressRule{ + { + Description: "test", + Protocol: infrav1.SecurityGroupProtocolTCP, + FromPort: 9345, + ToPort: 9345, + }, + }, + }, + expectedAdditionalIngresRule: infrav1.IngressRule{ + Description: "test", + Protocol: infrav1.SecurityGroupProtocolTCP, + FromPort: 9345, + ToPort: 9345, + SourceSecurityGroupIDs: []string{"cp-sg-id"}, + }, + }, + { + name: "custom security group id is used", + controlPlaneLBSpec: &infrav1.AWSLoadBalancerSpec{ + IngressRules: []infrav1.IngressRule{ + { + Description: "test", + Protocol: infrav1.SecurityGroupProtocolTCP, + FromPort: 9345, + ToPort: 9345, + SourceSecurityGroupIDs: []string{"test"}, + }, + }, + }, + expectedAdditionalIngresRule: infrav1.IngressRule{ + Description: "test", + Protocol: infrav1.SecurityGroupProtocolTCP, + FromPort: 9345, + ToPort: 9345, + SourceSecurityGroupIDs: []string{"test"}, + }, + }, + { + name: "another security group role is used", + controlPlaneLBSpec: &infrav1.AWSLoadBalancerSpec{ + IngressRules: []infrav1.IngressRule{ + { + Description: "test", + Protocol: infrav1.SecurityGroupProtocolTCP, + FromPort: 9345, + ToPort: 9345, + SourceSecurityGroupRoles: []infrav1.SecurityGroupRole{infrav1.SecurityGroupNode}, + }, + }, + }, + expectedAdditionalIngresRule: infrav1.IngressRule{ + Description: "test", + Protocol: infrav1.SecurityGroupProtocolTCP, + FromPort: 9345, + ToPort: 9345, + SourceSecurityGroupIDs: []string{"node-sg-id"}, + }, + }, + { + name: "another security group role and a custom security group id is used", + controlPlaneLBSpec: &infrav1.AWSLoadBalancerSpec{ + IngressRules: []infrav1.IngressRule{ + { + Description: "test", + Protocol: infrav1.SecurityGroupProtocolTCP, + FromPort: 9345, + ToPort: 9345, + SourceSecurityGroupIDs: []string{"test"}, + SourceSecurityGroupRoles: []infrav1.SecurityGroupRole{infrav1.SecurityGroupNode}, + }, + }, + }, + expectedAdditionalIngresRule: infrav1.IngressRule{ + Description: "test", + Protocol: infrav1.SecurityGroupProtocolTCP, + FromPort: 9345, + ToPort: 9345, + SourceSecurityGroupIDs: []string{"test", "node-sg-id"}, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + cs, err := scope.NewClusterScope(scope.ClusterScopeParams{ + Client: fake.NewClientBuilder().WithScheme(scheme).Build(), + Cluster: &clusterv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{Name: "test-cluster"}, + }, + AWSCluster: &infrav1.AWSCluster{ + Spec: infrav1.AWSClusterSpec{ + ControlPlaneLoadBalancer: tc.controlPlaneLBSpec, + }, + Status: infrav1.AWSClusterStatus{ + Network: infrav1.NetworkStatus{ + SecurityGroups: map[infrav1.SecurityGroupRole]infrav1.SecurityGroup{ + infrav1.SecurityGroupControlPlane: { + ID: "cp-sg-id", + }, + infrav1.SecurityGroupNode: { + ID: "node-sg-id", + }, + }, + }, + }, + }, + }) + if err != nil { + t.Fatalf("Failed to create test context: %v", err) + } + + s := NewService(cs, testSecurityGroupRoles) + rules, err := s.getSecurityGroupIngressRules(infrav1.SecurityGroupControlPlane) + if err != nil { + t.Fatalf("Failed to lookup controlplane security group ingress rules: %v", err) + } + + found := false + for _, r := range rules { + if r.Description == "test" { + found = true + + if r.Protocol != tc.expectedAdditionalIngresRule.Protocol { + t.Fatalf("Expected protocol %s, got %s", tc.expectedAdditionalIngresRule.Protocol, r.Protocol) + } + + if r.FromPort != tc.expectedAdditionalIngresRule.FromPort { + t.Fatalf("Expected from port %d, got %d", tc.expectedAdditionalIngresRule.FromPort, r.FromPort) + } + + if r.ToPort != tc.expectedAdditionalIngresRule.ToPort { + t.Fatalf("Expected to port %d, got %d", tc.expectedAdditionalIngresRule.ToPort, r.ToPort) + } + + if !reflect.DeepEqual(r.SourceSecurityGroupIDs, tc.expectedAdditionalIngresRule.SourceSecurityGroupIDs) { + t.Fatalf("Expected source security group IDs %v, got %v", tc.expectedAdditionalIngresRule.SourceSecurityGroupIDs, r.SourceSecurityGroupIDs) + } + } + } + + if !found { + t.Fatal("Additional ingress rule was not found") + } + }) + } +} + +func TestControlPlaneLoadBalancerIngressRules(t *testing.T) { + scheme := runtime.NewScheme() + _ = infrav1.AddToScheme(scheme) + + testCases := []struct { + name string + controlPlaneLBSpec *infrav1.AWSLoadBalancerSpec + //useIPV6 bool + expectedIngresRules infrav1.IngressRules + }{ + { + name: "when no ingress rules are passed the default is set", + controlPlaneLBSpec: &infrav1.AWSLoadBalancerSpec{}, + //useIPV6: false, + expectedIngresRules: infrav1.IngressRules{ + infrav1.IngressRule{ + Description: "Kubernetes API", + Protocol: infrav1.SecurityGroupProtocolTCP, + FromPort: 6443, + ToPort: 6443, + CidrBlocks: []string{services.AnyIPv4CidrBlock}, + }, + }, + }, + //{ + // name: "when no ingress rules are passed and when using ipv6, the default for ipv6 is set", + // controlPlaneLBSpec: &infrav1.AWSLoadBalancerSpec{}, + // //useIPV6: true, + // expectedIngresRules: infrav1.IngressRules{ + // infrav1.IngressRule{ + // Description: "Kubernetes API IPv6", + // Protocol: infrav1.SecurityGroupProtocolTCP, + // FromPort: 6443, + // ToPort: 6443, + // //IPv6CidrBlocks: []string{services.AnyIPv6CidrBlock}, + // }, + // }, + //}, + { + name: "defined rules are used", + controlPlaneLBSpec: &infrav1.AWSLoadBalancerSpec{ + IngressRules: infrav1.IngressRules{ + { + Description: "My custom ingress rule", + Protocol: infrav1.SecurityGroupProtocolTCP, + FromPort: 1234, + ToPort: 1234, + CidrBlocks: []string{"172.126.1.1/0"}, + }, + }, + }, + //useIPV6: false, + expectedIngresRules: infrav1.IngressRules{ + infrav1.IngressRule{ + Description: "My custom ingress rule", + Protocol: infrav1.SecurityGroupProtocolTCP, + FromPort: 1234, + ToPort: 1234, + CidrBlocks: []string{"172.126.1.1/0"}, + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + vpcSpec := infrav1.VPCSpec{} + //if tc.useIPV6 { + // vpcSpec = infrav1.VPCSpec{ + // IPv6: &infrav1.IPv6{}, + // } + //} + + cs, err := scope.NewClusterScope(scope.ClusterScopeParams{ + Client: fake.NewClientBuilder().WithScheme(scheme).Build(), + Cluster: &clusterv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{Name: "test-cluster"}, + }, + AWSCluster: &infrav1.AWSCluster{ + Spec: infrav1.AWSClusterSpec{ + ControlPlaneLoadBalancer: tc.controlPlaneLBSpec, + NetworkSpec: infrav1.NetworkSpec{ + VPC: vpcSpec, + }, + }, + }, + }) + if err != nil { + t.Fatalf("Failed to create test context: %v", err) + } + + s := NewService(cs, testSecurityGroupRoles) + rules, err := s.getSecurityGroupIngressRules(infrav1.SecurityGroupAPIServerLB) + if err != nil { + t.Fatalf("Failed to lookup controlplane load balancer security group ingress rules: %v", err) + } + + g := NewGomegaWithT(t) + g.Expect(rules).To(Equal(tc.expectedIngresRules)) + }) + } +} + func TestDeleteSecurityGroups(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() diff --git a/spectro/generated/core-global.yaml b/spectro/generated/core-global.yaml index 53ab6e77e0..d27c0ebd28 100644 --- a/spectro/generated/core-global.yaml +++ b/spectro/generated/core-global.yaml @@ -2403,6 +2403,13 @@ spec: resources managed by the AWS provider, in addition to the ones added by default. type: object + associateOIDCProvider: + default: false + description: AssociateOIDCProvider can be enabled to automatically + create an identity provider and install the pod identity webhook + from AWS for use with IRSA. This will only work if the S3Bucket + is configured properly. + type: boolean bastion: description: Bastion contains options to configure the bastion host. properties: @@ -2475,6 +2482,67 @@ spec: description: HealthCheckProtocol sets the protocol type for classic ELB health check target default value is ClassicELBProtocolSSL type: string + ingressRules: + description: IngressRules sets the additional ingress rules for + the control plane load balancer. If no source security group + ids are specified, the default control plane security group + will be used. + 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 + 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). + enum: + - "-1" + - "4" + - tcp + - udp + - icmp + - "58" + 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. + 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 name: description: Name sets the name of the classic ELB load balancer. As per AWS, the name must be unique within your set of load @@ -2681,9 +2749,10 @@ spec: type: string s3Bucket: description: S3Bucket contains options to configure a supporting S3 - bucket for this cluster - currently used for nodes requiring Ignition - (https://coreos.github.io/ignition/) for bootstrapping (requires - BootstrapFormatIgnition feature flag to be enabled). + bucket for this cluster - Used for nodes requiring Ignition (https://coreos.github.io/ignition/) + for bootstrapping (requires BootstrapFormatIgnition feature flag + to be enabled) and for storing OIDC endpoint certificates for use + with IRSA properties: controlPlaneIAMInstanceProfile: description: ControlPlaneIAMInstanceProfile is a name of the IAMInstanceProfile, @@ -3112,13 +3181,24 @@ spec: 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 protocol: - description: SecurityGroupProtocol defines the protocol - type for a security group rule. + description: Protocol is the protocol for the ingress + rule. Accepted values are "-1" (all), "4" (IP in + IP),"tcp", "udp", "icmp", and "58" (ICMPv6). + enum: + - "-1" + - "4" + - tcp + - udp + - icmp + - "58" type: string sourceSecurityGroupIds: description: The security group id to allow access @@ -3126,7 +3206,18 @@ spec: 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. + type: string + type: array toPort: + description: ToPort is the end of port range. format: int64 type: integer required: @@ -3153,6 +3244,18 @@ spec: security group to its unique name, if any. type: object type: object + oidcProvider: + description: OIDCProvider holds the status of the identity provider + for this cluster + properties: + arn: + description: ARN holds the ARN of the provider + type: string + trustPolicy: + description: TrustPolicy contains the boilerplate IAM trust policy + to use for IRSA + type: string + type: object ready: default: false type: boolean @@ -3289,11 +3392,11 @@ spec: Optional' properties: name: - description: Name is unique within a namespace to reference a + description: name is unique within a namespace to reference a secret resource. type: string namespace: - description: Namespace defines the space within which the secret + description: namespace defines the space within which the secret name must be unique. type: string type: object @@ -3926,6 +4029,13 @@ spec: add to AWS resources managed by the AWS provider, in addition to the ones added by default. type: object + associateOIDCProvider: + default: false + description: AssociateOIDCProvider can be enabled to automatically + create an identity provider and install the pod identity + webhook from AWS for use with IRSA. This will only work + if the S3Bucket is configured properly. + type: boolean bastion: description: Bastion contains options to configure the bastion host. @@ -4003,6 +4113,68 @@ spec: for classic ELB health check target default value is ClassicELBProtocolSSL type: string + ingressRules: + description: IngressRules sets the additional ingress + rules for the control plane load balancer. If no source + security group ids are specified, the default control + plane security group will be used. + 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 + 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). + enum: + - "-1" + - "4" + - tcp + - udp + - icmp + - "58" + 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. + 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 name: description: Name sets the name of the classic ELB load balancer. As per AWS, the name must be unique within @@ -4220,9 +4392,10 @@ spec: type: string s3Bucket: description: S3Bucket contains options to configure a supporting - S3 bucket for this cluster - currently used for nodes requiring - Ignition (https://coreos.github.io/ignition/) for bootstrapping - (requires BootstrapFormatIgnition feature flag to be enabled). + S3 bucket for this cluster - Used for nodes requiring Ignition + (https://coreos.github.io/ignition/) for bootstrapping (requires + BootstrapFormatIgnition feature flag to be enabled) and + for storing OIDC endpoint certificates for use with IRSA properties: controlPlaneIAMInstanceProfile: description: ControlPlaneIAMInstanceProfile is a name @@ -11017,6 +11190,122 @@ spec: description: AWSManagedControlPlaneSpec defines the desired state of an Amazon EKS Cluster. properties: + VpcCni: + description: VpcCni is used to set configuration options for the VPC + CNI plugin + properties: + env: + description: Env defines a list of environment variables to apply + to the `aws-node` DaemonSet + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + type: object additionalTags: additionalProperties: type: string @@ -12030,13 +12319,24 @@ spec: 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 protocol: - description: SecurityGroupProtocol defines the protocol - type for a security group rule. + description: Protocol is the protocol for the ingress + rule. Accepted values are "-1" (all), "4" (IP in + IP),"tcp", "udp", "icmp", and "58" (ICMPv6). + enum: + - "-1" + - "4" + - tcp + - udp + - icmp + - "58" type: string sourceSecurityGroupIds: description: The security group id to allow access @@ -12044,7 +12344,18 @@ spec: 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. + type: string + type: array toPort: + description: ToPort is the end of port range. format: int64 type: integer required: @@ -13724,7 +14035,7 @@ spec: containers: - args: - --leader-elect - - --feature-gates=EKS=${CAPA_EKS:=true},EKSEnableIAM=${CAPA_EKS_IAM:=false},EKSAllowAddRoles=${CAPA_EKS_ADD_ROLES:=false},EKSFargate=${EXP_EKS_FARGATE:=false},MachinePool=${EXP_MACHINE_POOL:=false},EventBridgeInstanceState=${EVENT_BRIDGE_INSTANCE_STATE:=false},AutoControllerIdentityCreator=${AUTO_CONTROLLER_IDENTITY_CREATOR:=true},BootstrapFormatIgnition=${EXP_BOOTSTRAP_FORMAT_IGNITION:=false} + - --feature-gates=EKS=${CAPA_EKS:=true},EKSEnableIAM=${CAPA_EKS_IAM:=false},EKSAllowAddRoles=${CAPA_EKS_ADD_ROLES:=false},EKSFargate=${EXP_EKS_FARGATE:=false},MachinePool=${EXP_MACHINE_POOL:=false},EventBridgeInstanceState=${EVENT_BRIDGE_INSTANCE_STATE:=false},AutoControllerIdentityCreator=${AUTO_CONTROLLER_IDENTITY_CREATOR:=true},BootstrapFormatIgnition=${EXP_BOOTSTRAP_FORMAT_IGNITION:=false},ExternalResourceGC=${EXP_EXTERNAL_RESOURCE_GC:=false} - --v=${CAPA_LOGLEVEL:=0} - --metrics-bind-addr=127.0.0.1:8080 image: gcr.io/k8s-staging-cluster-api-aws/cluster-api-aws-controller:latest diff --git a/spectro/run.sh b/spectro/run.sh index 8dd7c6d0a3..b860ffb882 100755 --- a/spectro/run.sh +++ b/spectro/run.sh @@ -2,5 +2,5 @@ rm ./generated/* -kustomize build --load_restrictor none global > ./generated/core-global.yaml -kustomize build --load_restrictor none base > ./generated/core-base.yaml \ No newline at end of file +kustomize build --load-restrictor LoadRestrictionsNone global > ./generated/core-global.yaml +kustomize build --load-restrictor LoadRestrictionsNone base > ./generated/core-base.yaml