diff --git a/api/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/awsmachine_types.go b/api/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/awsmachine_types.go index 26e733b9c..39a649a0e 100644 --- a/api/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/awsmachine_types.go +++ b/api/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/awsmachine_types.go @@ -113,6 +113,11 @@ type AWSMachineSpec struct { // +optional PublicIP *bool `json:"publicIP,omitempty"` + // ElasticIPPool is the configuration to allocate Public IPv4 address (Elastic IP/EIP) from user-defined pool. + // + // +optional + ElasticIPPool *ElasticIPPool `json:"elasticIpPool,omitempty"` + // AdditionalSecurityGroups is an array of references to security groups that should be applied to the // instance. These security groups would be set in addition to any security groups defined // at the cluster level or in the actuator. It is possible to specify either IDs of Filters. Using Filters @@ -188,6 +193,10 @@ type AWSMachineSpec struct { // PrivateDNSName is the options for the instance hostname. // +optional PrivateDNSName *PrivateDNSName `json:"privateDnsName,omitempty"` + + // CapacityReservationID specifies the target Capacity Reservation into which the instance should be launched. + // +optional + CapacityReservationID *string `json:"capacityReservationId,omitempty"` } // CloudInit defines options related to the bootstrapping systems where diff --git a/api/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/network_types.go b/api/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/network_types.go index cd3042b71..2e123cbc3 100644 --- a/api/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/network_types.go +++ b/api/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/network_types.go @@ -455,6 +455,22 @@ type VPCSpec struct { // +optional // +kubebuilder:validation:Enum:=ip-name;resource-name PrivateDNSHostnameTypeOnLaunch *string `json:"privateDnsHostnameTypeOnLaunch,omitempty"` + + // ElasticIPPool contains specific configuration to allocate Public IPv4 address (Elastic IP) from user-defined pool + // brought to AWS for core infrastructure resources, like NAT Gateways and Public Network Load Balancers for + // the API Server. + // +optional + ElasticIPPool *ElasticIPPool `json:"elasticIpPool,omitempty"` + + // SubnetSchema specifies how CidrBlock should be divided on subnets in the VPC depending on the number of AZs. + // PreferPrivate - one private subnet for each AZ plus one other subnet that will be further sub-divided for the public subnets. + // PreferPublic - have the reverse logic of PreferPrivate, one public subnet for each AZ plus one other subnet + // that will be further sub-divided for the private subnets. + // Defaults to PreferPrivate + // +optional + // +kubebuilder:default=PreferPrivate + // +kubebuilder:validation:Enum=PreferPrivate;PreferPublic + SubnetSchema *SubnetSchemaType `json:"subnetSchema,omitempty"` } // String returns a string representation of the VPC. @@ -477,6 +493,22 @@ func (v *VPCSpec) IsIPv6Enabled() bool { return v.IPv6 != nil } +// GetElasticIPPool returns the custom Elastic IP Pool configuration when present. +func (v *VPCSpec) GetElasticIPPool() *ElasticIPPool { + return v.ElasticIPPool +} + +// GetPublicIpv4Pool returns the custom public IPv4 pool brought to AWS when present. +func (v *VPCSpec) GetPublicIpv4Pool() *string { + if v.ElasticIPPool == nil { + return nil + } + if v.ElasticIPPool.PublicIpv4Pool != nil { + return v.ElasticIPPool.PublicIpv4Pool + } + return nil +} + // SubnetSpec configures an AWS Subnet. type SubnetSpec struct { // ID defines a unique identifier to reference this resource. @@ -715,6 +747,17 @@ func (s Subnets) FilterPrivate() (res Subnets) { return } +// FilterNonCni returns the subnets that are NOT intended for usage with the CNI pod network +// (i.e. do NOT have the `sigs.k8s.io/cluster-api-provider-aws/association=secondary` tag). +func (s Subnets) FilterNonCni() (res Subnets) { + for _, x := range s { + if x.Tags[NameAWSSubnetAssociation] != SecondarySubnetTagValue { + res = append(res, x) + } + } + return +} + // FilterPublic returns a slice containing all subnets marked as public. func (s Subnets) FilterPublic() (res Subnets) { for _, x := range s { @@ -897,6 +940,10 @@ type IngressRule struct { // The field will be combined with source security group IDs if specified. // +optional SourceSecurityGroupRoles []SecurityGroupRole `json:"sourceSecurityGroupRoles,omitempty"` + + // NatGatewaysIPsSource use the NAT gateways IPs as the source for the ingress rule. + // +optional + NatGatewaysIPsSource bool `json:"natGatewaysIPsSource,omitempty"` } // String returns a string representation of the ingress rule. @@ -1002,3 +1049,57 @@ func (z ZoneType) String() string { func (z ZoneType) Equal(other ZoneType) bool { return z == other } + +// ElasticIPPool allows configuring a Elastic IP pool for resources allocating +// public IPv4 addresses on public subnets. +type ElasticIPPool struct { + // PublicIpv4Pool sets a custom Public IPv4 Pool used to create Elastic IP address for resources + // created in public IPv4 subnets. Every IPv4 address, Elastic IP, will be allocated from the custom + // Public IPv4 pool that you brought to AWS, instead of Amazon-provided pool. The public IPv4 pool + // resource ID starts with 'ipv4pool-ec2'. + // + // +kubebuilder:validation:MaxLength=30 + // +optional + PublicIpv4Pool *string `json:"publicIpv4Pool,omitempty"` + + // PublicIpv4PoolFallBackOrder defines the fallback action when the Public IPv4 Pool has been exhausted, + // no more IPv4 address available in the pool. + // + // When set to 'amazon-pool', the controller check if the pool has available IPv4 address, when pool has reached the + // IPv4 limit, the address will be claimed from Amazon-pool (default). + // + // When set to 'none', the controller will fail the Elastic IP allocation when the publicIpv4Pool is exhausted. + // + // +kubebuilder:validation:Enum:=amazon-pool;none + // +optional + PublicIpv4PoolFallBackOrder *PublicIpv4PoolFallbackOrder `json:"publicIpv4PoolFallbackOrder,omitempty"` + + // TODO(mtulio): add future support of user-defined Elastic IP to allow users to assign BYO Public IP from + // 'static'/preallocated amazon-provided IPsstrucute currently holds only 'BYO Public IP from Public IPv4 Pool' (user brought to AWS), + // although a dedicated structure would help to hold 'BYO Elastic IP' variants like: + // - AllocationIdPoolApiLoadBalancer: an user-defined (static) IP address to the Public API Load Balancer. + // - AllocationIdPoolNatGateways: an user-defined (static) IP address to allocate to NAT Gateways (egress traffic). +} + +// PublicIpv4PoolFallbackOrder defines the list of available fallback action when the PublicIpv4Pool is exhausted. +// 'none' let the controllers return failures when the PublicIpv4Pool is exhausted - no more IPv4 available. +// 'amazon-pool' let the controllers to skip the PublicIpv4Pool and use the Amazon pool, the default. +// +kubebuilder:validation:XValidation:rule="self in ['none','amazon-pool']",message="allowed values are 'none' and 'amazon-pool'" +type PublicIpv4PoolFallbackOrder string + +const ( + // PublicIpv4PoolFallbackOrderAmazonPool refers to use Amazon-pool Public IPv4 Pool as a fallback strategy. + PublicIpv4PoolFallbackOrderAmazonPool = PublicIpv4PoolFallbackOrder("amazon-pool") + + // PublicIpv4PoolFallbackOrderNone refers to not use any fallback strategy. + PublicIpv4PoolFallbackOrderNone = PublicIpv4PoolFallbackOrder("none") +) + +func (r PublicIpv4PoolFallbackOrder) String() string { + return string(r) +} + +// Equal compares PublicIpv4PoolFallbackOrder types and return true if input param is equal. +func (r PublicIpv4PoolFallbackOrder) Equal(e PublicIpv4PoolFallbackOrder) bool { + return r == e +} diff --git a/api/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/types.go b/api/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/types.go index abf92ae4e..978d5310f 100644 --- a/api/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/types.go +++ b/api/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/types.go @@ -17,11 +17,19 @@ limitations under the License. package v1beta2 import ( + "strings" + "k8s.io/apimachinery/pkg/util/sets" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" ) +const ( + // PreventDeletionLabel can be used in situations where preventing delation is allowed. The docs + // and the CRD will call this out where its allowed. + PreventDeletionLabel = "aws.cluster.x-k8s.io/prevent-deletion" +) + // AWSResourceReference is a reference to a specific AWS resource by ID or filters. // Only one of ID or Filters may be specified. Specifying more than one will result in // a validation error. @@ -249,6 +257,10 @@ type Instance struct { // PublicIPOnLaunch is the option to associate a public IP on instance launch // +optional PublicIPOnLaunch *bool `json:"publicIPOnLaunch,omitempty"` + + // CapacityReservationID specifies the target Capacity Reservation into which the instance should be launched. + // +optional + CapacityReservationID *string `json:"capacityReservationId,omitempty"` } // InstanceMetadataState describes the state of InstanceMetadataOptions.HttpEndpoint and InstanceMetadataOptions.InstanceMetadataTags @@ -439,3 +451,19 @@ type PrivateDNSName struct { // +kubebuilder:validation:Enum:=ip-name;resource-name HostnameType *string `json:"hostnameType,omitempty"` } + +// SubnetSchemaType specifies how given network should be divided on subnets +// in the VPC depending on the number of AZs. +type SubnetSchemaType string + +// Name returns subnet schema type name without prefix. +func (s *SubnetSchemaType) Name() string { + return strings.ToLower(strings.TrimPrefix(string(*s), "Prefer")) +} + +var ( + // SubnetSchemaPreferPrivate allocates more subnets in the VPC to private subnets. + SubnetSchemaPreferPrivate = SubnetSchemaType("PreferPrivate") + // SubnetSchemaPreferPublic allocates more subnets in the VPC to public subnets. + SubnetSchemaPreferPublic = SubnetSchemaType("PreferPublic") +) diff --git a/api/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/zz_generated.deepcopy.go b/api/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/zz_generated.deepcopy.go index 81b8a8d31..01a210366 100644 --- a/api/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/zz_generated.deepcopy.go +++ b/api/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2/zz_generated.deepcopy.go @@ -700,6 +700,11 @@ func (in *AWSMachineSpec) DeepCopyInto(out *AWSMachineSpec) { *out = new(bool) **out = **in } + if in.ElasticIPPool != nil { + in, out := &in.ElasticIPPool, &out.ElasticIPPool + *out = new(ElasticIPPool) + (*in).DeepCopyInto(*out) + } if in.AdditionalSecurityGroups != nil { in, out := &in.AdditionalSecurityGroups, &out.AdditionalSecurityGroups *out = make([]AWSResourceReference, len(*in)) @@ -762,6 +767,11 @@ func (in *AWSMachineSpec) DeepCopyInto(out *AWSMachineSpec) { *out = new(PrivateDNSName) (*in).DeepCopyInto(*out) } + if in.CapacityReservationID != nil { + in, out := &in.CapacityReservationID, &out.CapacityReservationID + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSMachineSpec. @@ -1281,6 +1291,31 @@ func (in *CloudInit) DeepCopy() *CloudInit { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ElasticIPPool) DeepCopyInto(out *ElasticIPPool) { + *out = *in + if in.PublicIpv4Pool != nil { + in, out := &in.PublicIpv4Pool, &out.PublicIpv4Pool + *out = new(string) + **out = **in + } + if in.PublicIpv4PoolFallBackOrder != nil { + in, out := &in.PublicIpv4PoolFallBackOrder, &out.PublicIpv4PoolFallBackOrder + *out = new(PublicIpv4PoolFallbackOrder) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ElasticIPPool. +func (in *ElasticIPPool) DeepCopy() *ElasticIPPool { + if in == nil { + return nil + } + out := new(ElasticIPPool) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Filter) DeepCopyInto(out *Filter) { *out = *in @@ -1564,6 +1599,11 @@ func (in *Instance) DeepCopyInto(out *Instance) { *out = new(bool) **out = **in } + if in.CapacityReservationID != nil { + in, out := &in.CapacityReservationID, &out.CapacityReservationID + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance. @@ -2157,6 +2197,16 @@ func (in *VPCSpec) DeepCopyInto(out *VPCSpec) { *out = new(string) **out = **in } + if in.ElasticIPPool != nil { + in, out := &in.ElasticIPPool, &out.ElasticIPPool + *out = new(ElasticIPPool) + (*in).DeepCopyInto(*out) + } + if in.SubnetSchema != nil { + in, out := &in.SubnetSchema, &out.SubnetSchema + *out = new(SubnetSchemaType) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VPCSpec. diff --git a/hack/third-party/capa/go.mod b/hack/third-party/capa/go.mod index fff7b3aba..dc7af1db2 100644 --- a/hack/third-party/capa/go.mod +++ b/hack/third-party/capa/go.mod @@ -5,7 +5,7 @@ module github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/ex go 1.21 -require sigs.k8s.io/cluster-api-provider-aws/v2 v2.5.2 +require sigs.k8s.io/cluster-api-provider-aws/v2 v2.6.1 require ( github.com/aws/aws-sdk-go v1.51.17 // indirect diff --git a/hack/third-party/capa/go.sum b/hack/third-party/capa/go.sum index a52a446af..ccd66c9bd 100644 --- a/hack/third-party/capa/go.sum +++ b/hack/third-party/capa/go.sum @@ -38,6 +38,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 h1:0VpGH+cDhbDtdcweoyCVsF3fhN8kejK6rFe/2FFX2nU= @@ -183,8 +185,8 @@ k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCf k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/cluster-api v1.7.1 h1:JkMAbAMzBM+WBHxXLTJXTiCisv1PAaHRzld/3qrmLYY= sigs.k8s.io/cluster-api v1.7.1/go.mod h1:V9ZhKLvQtsDODwjXOKgbitjyCmC71yMBwDcMyNNIov0= -sigs.k8s.io/cluster-api-provider-aws/v2 v2.5.2 h1:KIIgGf7CmYcvmrluwq7kPO8ZIfCduVtJ2aFR8GvA6IU= -sigs.k8s.io/cluster-api-provider-aws/v2 v2.5.2/go.mod h1:eQodl6ZvSu8PVNsOPt5TrqDc8gmCsor+BZHQQFX2Gns= +sigs.k8s.io/cluster-api-provider-aws/v2 v2.6.1 h1:vbZUYEB7OfPlfHk6wis+UrvRLTqv5F4Nrjl2WDJ1kiw= +sigs.k8s.io/cluster-api-provider-aws/v2 v2.6.1/go.mod h1:1aq1EZbirRW6NC2gYUFCc7cVFwX9PM/vDvoU+2oGPuw= sigs.k8s.io/controller-runtime v0.17.3 h1:65QmN7r3FWgTxDMz9fvGnO1kbf2nu+acg9p2R9oYYYk= sigs.k8s.io/controller-runtime v0.17.3/go.mod h1:N0jpP5Lo7lMTF9aL56Z/B2oWBJjey6StQM0jRbKQXtY= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= diff --git a/test/e2e/data/shared/v1beta1-capa/metadata.yaml b/test/e2e/data/shared/v1beta1-capa/metadata.yaml index 6b3e37e9c..e0f2be0e5 100644 --- a/test/e2e/data/shared/v1beta1-capa/metadata.yaml +++ b/test/e2e/data/shared/v1beta1-capa/metadata.yaml @@ -9,5 +9,5 @@ apiVersion: clusterctl.cluster.x-k8s.io/v1alpha3 releaseSeries: - major: 2 - minor: 5 + minor: 6 contract: v1beta1