sigs.k8s.io/cluster-api-provider-aws@v1.5.5/api/v1alpha4/types.go (about)

     1  /*
     2  Copyright 2021 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  	http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package v1alpha4
    18  
    19  import (
    20  	"fmt"
    21  	"sort"
    22  	"time"
    23  
    24  	"k8s.io/apimachinery/pkg/util/sets"
    25  
    26  	clusterv1alpha4 "sigs.k8s.io/cluster-api/api/v1alpha4"
    27  )
    28  
    29  const (
    30  	// DefaultNameSuffix is the default suffix appended to all AWS IAM roles created by clusterawsadm.
    31  	DefaultNameSuffix = ".cluster-api-provider-aws.sigs.k8s.io"
    32  )
    33  
    34  // AWSResourceReference is a reference to a specific AWS resource by ID, ARN, or filters.
    35  // Only one of ID, ARN or Filters may be specified. Specifying more than one will result in
    36  // a validation error.
    37  type AWSResourceReference struct {
    38  	// ID of resource
    39  	// +optional
    40  	ID *string `json:"id,omitempty"`
    41  
    42  	// ARN of resource
    43  	// +optional
    44  	ARN *string `json:"arn,omitempty"`
    45  
    46  	// Filters is a set of key/value pairs used to identify a resource
    47  	// They are applied according to the rules defined by the AWS API:
    48  	// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Filtering.html
    49  	// +optional
    50  	Filters []Filter `json:"filters,omitempty"`
    51  }
    52  
    53  // AMIReference is a reference to a specific AWS resource by ID, ARN, or filters.
    54  // Only one of ID, ARN or Filters may be specified. Specifying more than one will result in
    55  // a validation error.
    56  type AMIReference struct {
    57  	// ID of resource
    58  	// +optional
    59  	ID *string `json:"id,omitempty"`
    60  
    61  	// EKSOptimizedLookupType If specified, will look up an EKS Optimized image in SSM Parameter store
    62  	// +kubebuilder:validation:Enum:=AmazonLinux;AmazonLinuxGPU
    63  	// +optional
    64  	EKSOptimizedLookupType *EKSAMILookupType `json:"eksLookupType,omitempty"`
    65  }
    66  
    67  // AWSMachineTemplateResource describes the data needed to create am AWSMachine from a template
    68  type AWSMachineTemplateResource struct {
    69  	// Spec is the specification of the desired behavior of the machine.
    70  	Spec AWSMachineSpec `json:"spec"`
    71  }
    72  
    73  // Filter is a filter used to identify an AWS resource
    74  type Filter struct {
    75  	// Name of the filter. Filter names are case-sensitive.
    76  	Name string `json:"name"`
    77  
    78  	// Values includes one or more filter values. Filter values are case-sensitive.
    79  	Values []string `json:"values"`
    80  }
    81  
    82  // AWSMachineProviderConditionType is a valid value for AWSMachineProviderCondition.Type.
    83  type AWSMachineProviderConditionType string
    84  
    85  // Valid conditions for an AWS machine instance.
    86  const (
    87  	// MachineCreated indicates whether the machine has been created or not. If not,
    88  	// it should include a reason and message for the failure.
    89  	MachineCreated AWSMachineProviderConditionType = "MachineCreated"
    90  )
    91  
    92  // NetworkStatus encapsulates AWS networking resources.
    93  type NetworkStatus struct {
    94  	// SecurityGroups is a map from the role/kind of the security group to its unique name, if any.
    95  	SecurityGroups map[SecurityGroupRole]SecurityGroup `json:"securityGroups,omitempty"`
    96  
    97  	// APIServerELB is the Kubernetes api server classic load balancer.
    98  	APIServerELB ClassicELB `json:"apiServerElb,omitempty"`
    99  }
   100  
   101  // ClassicELBScheme defines the scheme of a classic load balancer.
   102  type ClassicELBScheme string
   103  
   104  var (
   105  	// ClassicELBSchemeInternetFacing defines an internet-facing, publicly
   106  	// accessible AWS Classic ELB scheme.
   107  	ClassicELBSchemeInternetFacing = ClassicELBScheme("internet-facing")
   108  
   109  	// ClassicELBSchemeInternal defines an internal-only facing
   110  	// load balancer internal to an ELB.
   111  	ClassicELBSchemeInternal = ClassicELBScheme("internal")
   112  )
   113  
   114  func (e ClassicELBScheme) String() string {
   115  	return string(e)
   116  }
   117  
   118  // ClassicELBProtocol defines listener protocols for a classic load balancer.
   119  type ClassicELBProtocol string
   120  
   121  var (
   122  	// ClassicELBProtocolTCP defines the ELB API string representing the TCP protocol.
   123  	ClassicELBProtocolTCP = ClassicELBProtocol("TCP")
   124  
   125  	// ClassicELBProtocolSSL defines the ELB API string representing the TLS protocol.
   126  	ClassicELBProtocolSSL = ClassicELBProtocol("SSL")
   127  
   128  	// ClassicELBProtocolHTTP defines the ELB API string representing the HTTP protocol at L7.
   129  	ClassicELBProtocolHTTP = ClassicELBProtocol("HTTP")
   130  
   131  	// ClassicELBProtocolHTTPS defines the ELB API string representing the HTTP protocol at L7.
   132  	ClassicELBProtocolHTTPS = ClassicELBProtocol("HTTPS")
   133  )
   134  
   135  // ClassicELB defines an AWS classic load balancer.
   136  type ClassicELB struct {
   137  	// The name of the load balancer. It must be unique within the set of load balancers
   138  	// defined in the region. It also serves as identifier.
   139  	Name string `json:"name,omitempty"`
   140  
   141  	// DNSName is the dns name of the load balancer.
   142  	DNSName string `json:"dnsName,omitempty"`
   143  
   144  	// Scheme is the load balancer scheme, either internet-facing or private.
   145  	Scheme ClassicELBScheme `json:"scheme,omitempty"`
   146  
   147  	// AvailabilityZones is an array of availability zones in the VPC attached to the load balancer.
   148  	AvailabilityZones []string `json:"availabilityZones,omitempty"`
   149  
   150  	// SubnetIDs is an array of subnets in the VPC attached to the load balancer.
   151  	SubnetIDs []string `json:"subnetIds,omitempty"`
   152  
   153  	// SecurityGroupIDs is an array of security groups assigned to the load balancer.
   154  	SecurityGroupIDs []string `json:"securityGroupIds,omitempty"`
   155  
   156  	// Listeners is an array of classic elb listeners associated with the load balancer. There must be at least one.
   157  	Listeners []ClassicELBListener `json:"listeners,omitempty"`
   158  
   159  	// HealthCheck is the classic elb health check associated with the load balancer.
   160  	HealthCheck *ClassicELBHealthCheck `json:"healthChecks,omitempty"`
   161  
   162  	// Attributes defines extra attributes associated with the load balancer.
   163  	Attributes ClassicELBAttributes `json:"attributes,omitempty"`
   164  
   165  	// Tags is a map of tags associated with the load balancer.
   166  	Tags map[string]string `json:"tags,omitempty"`
   167  }
   168  
   169  // ClassicELBAttributes defines extra attributes associated with a classic load balancer.
   170  type ClassicELBAttributes struct {
   171  	// IdleTimeout is time that the connection is allowed to be idle (no data
   172  	// has been sent over the connection) before it is closed by the load balancer.
   173  	IdleTimeout time.Duration `json:"idleTimeout,omitempty"`
   174  
   175  	// CrossZoneLoadBalancing enables the classic load balancer load balancing.
   176  	// +optional
   177  	CrossZoneLoadBalancing bool `json:"crossZoneLoadBalancing,omitempty"`
   178  }
   179  
   180  // ClassicELBListener defines an AWS classic load balancer listener.
   181  type ClassicELBListener struct {
   182  	Protocol         ClassicELBProtocol `json:"protocol"`
   183  	Port             int64              `json:"port"`
   184  	InstanceProtocol ClassicELBProtocol `json:"instanceProtocol"`
   185  	InstancePort     int64              `json:"instancePort"`
   186  }
   187  
   188  // ClassicELBHealthCheck defines an AWS classic load balancer health check.
   189  type ClassicELBHealthCheck struct {
   190  	Target             string        `json:"target"`
   191  	Interval           time.Duration `json:"interval"`
   192  	Timeout            time.Duration `json:"timeout"`
   193  	HealthyThreshold   int64         `json:"healthyThreshold"`
   194  	UnhealthyThreshold int64         `json:"unhealthyThreshold"`
   195  }
   196  
   197  // AZSelectionScheme defines the scheme of selecting AZs.
   198  type AZSelectionScheme string
   199  
   200  var (
   201  	// AZSelectionSchemeOrdered will select AZs based on alphabetical order.
   202  	AZSelectionSchemeOrdered = AZSelectionScheme("Ordered")
   203  
   204  	// AZSelectionSchemeRandom will select AZs randomly.
   205  	AZSelectionSchemeRandom = AZSelectionScheme("Random")
   206  )
   207  
   208  // NetworkSpec encapsulates all things related to AWS network.
   209  type NetworkSpec struct {
   210  	// VPC configuration.
   211  	// +optional
   212  	VPC VPCSpec `json:"vpc,omitempty"`
   213  
   214  	// Subnets configuration.
   215  	// +optional
   216  	Subnets Subnets `json:"subnets,omitempty"`
   217  
   218  	// CNI configuration
   219  	// +optional
   220  	CNI *CNISpec `json:"cni,omitempty"`
   221  
   222  	// SecurityGroupOverrides is an optional set of security groups to use for cluster instances
   223  	// This is optional - if not provided new security groups will be created for the cluster
   224  	// +optional
   225  	SecurityGroupOverrides map[SecurityGroupRole]string `json:"securityGroupOverrides,omitempty"`
   226  }
   227  
   228  // VPCSpec configures an AWS VPC.
   229  type VPCSpec struct {
   230  	// ID is the vpc-id of the VPC this provider should use to create resources.
   231  	ID string `json:"id,omitempty"`
   232  
   233  	// CidrBlock is the CIDR block to be used when the provider creates a managed VPC.
   234  	// Defaults to 10.0.0.0/16.
   235  	CidrBlock string `json:"cidrBlock,omitempty"`
   236  
   237  	// InternetGatewayID is the id of the internet gateway associated with the VPC.
   238  	// +optional
   239  	InternetGatewayID *string `json:"internetGatewayId,omitempty"`
   240  
   241  	// Tags is a collection of tags describing the resource.
   242  	Tags Tags `json:"tags,omitempty"`
   243  
   244  	// AvailabilityZoneUsageLimit specifies the maximum number of availability zones (AZ) that
   245  	// should be used in a region when automatically creating subnets. If a region has more
   246  	// than this number of AZs then this number of AZs will be picked randomly when creating
   247  	// default subnets. Defaults to 3
   248  	// +kubebuilder:default=3
   249  	// +kubebuilder:validation:Minimum=1
   250  	AvailabilityZoneUsageLimit *int `json:"availabilityZoneUsageLimit,omitempty"`
   251  
   252  	// AvailabilityZoneSelection specifies how AZs should be selected if there are more AZs
   253  	// in a region than specified by AvailabilityZoneUsageLimit. There are 2 selection schemes:
   254  	// Ordered - selects based on alphabetical order
   255  	// Random - selects AZs randomly in a region
   256  	// Defaults to Ordered
   257  	// +kubebuilder:default=Ordered
   258  	// +kubebuilder:validation:Enum=Ordered;Random
   259  	AvailabilityZoneSelection *AZSelectionScheme `json:"availabilityZoneSelection,omitempty"`
   260  }
   261  
   262  // String returns a string representation of the VPC.
   263  func (v *VPCSpec) String() string {
   264  	return fmt.Sprintf("id=%s", v.ID)
   265  }
   266  
   267  // IsUnmanaged returns true if the VPC is unmanaged.
   268  func (v *VPCSpec) IsUnmanaged(clusterName string) bool {
   269  	return v.ID != "" && !v.Tags.HasOwned(clusterName)
   270  }
   271  
   272  // IsManaged returns true if VPC is managed.
   273  func (v *VPCSpec) IsManaged(clusterName string) bool {
   274  	return !v.IsUnmanaged(clusterName)
   275  }
   276  
   277  // SubnetSpec configures an AWS Subnet.
   278  type SubnetSpec struct {
   279  	// ID defines a unique identifier to reference this resource.
   280  	ID string `json:"id,omitempty"`
   281  
   282  	// CidrBlock is the CIDR block to be used when the provider creates a managed VPC.
   283  	CidrBlock string `json:"cidrBlock,omitempty"`
   284  
   285  	// AvailabilityZone defines the availability zone to use for this subnet in the cluster's region.
   286  	AvailabilityZone string `json:"availabilityZone,omitempty"`
   287  
   288  	// IsPublic defines the subnet as a public subnet. A subnet is public when it is associated with a route table that has a route to an internet gateway.
   289  	// +optional
   290  	IsPublic bool `json:"isPublic"`
   291  
   292  	// RouteTableID is the routing table id associated with the subnet.
   293  	// +optional
   294  	RouteTableID *string `json:"routeTableId,omitempty"`
   295  
   296  	// NatGatewayID is the NAT gateway id associated with the subnet.
   297  	// Ignored unless the subnet is managed by the provider, in which case this is set on the public subnet where the NAT gateway resides. It is then used to determine routes for private subnets in the same AZ as the public subnet.
   298  	// +optional
   299  	NatGatewayID *string `json:"natGatewayId,omitempty"`
   300  
   301  	// Tags is a collection of tags describing the resource.
   302  	Tags Tags `json:"tags,omitempty"`
   303  }
   304  
   305  // String returns a string representation of the subnet.
   306  func (s *SubnetSpec) String() string {
   307  	return fmt.Sprintf("id=%s/az=%s/public=%v", s.ID, s.AvailabilityZone, s.IsPublic)
   308  }
   309  
   310  // Subnets is a slice of Subnet.
   311  type Subnets []SubnetSpec
   312  
   313  // ToMap returns a map from id to subnet.
   314  func (s Subnets) ToMap() map[string]*SubnetSpec {
   315  	res := make(map[string]*SubnetSpec)
   316  	for i := range s {
   317  		x := s[i]
   318  		res[x.ID] = &x
   319  	}
   320  	return res
   321  }
   322  
   323  // IDs returns a slice of the subnet ids.
   324  func (s Subnets) IDs() []string {
   325  	res := []string{}
   326  	for _, subnet := range s {
   327  		res = append(res, subnet.ID)
   328  	}
   329  	return res
   330  }
   331  
   332  // FindByID returns a single subnet matching the given id or nil.
   333  func (s Subnets) FindByID(id string) *SubnetSpec {
   334  	for _, x := range s {
   335  		if x.ID == id {
   336  			return &x
   337  		}
   338  	}
   339  
   340  	return nil
   341  }
   342  
   343  // FindEqual returns a subnet spec that is equal to the one passed in.
   344  // Two subnets are defined equal to each other if their id is equal
   345  // or if they are in the same vpc and the cidr block is the same.
   346  func (s Subnets) FindEqual(spec *SubnetSpec) *SubnetSpec {
   347  	for _, x := range s {
   348  		if (spec.ID != "" && x.ID == spec.ID) || (spec.CidrBlock == x.CidrBlock) {
   349  			return &x
   350  		}
   351  	}
   352  	return nil
   353  }
   354  
   355  // FilterPrivate returns a slice containing all subnets marked as private.
   356  func (s Subnets) FilterPrivate() (res Subnets) {
   357  	for _, x := range s {
   358  		if !x.IsPublic {
   359  			res = append(res, x)
   360  		}
   361  	}
   362  	return
   363  }
   364  
   365  // FilterPublic returns a slice containing all subnets marked as public.
   366  func (s Subnets) FilterPublic() (res Subnets) {
   367  	for _, x := range s {
   368  		if x.IsPublic {
   369  			res = append(res, x)
   370  		}
   371  	}
   372  	return
   373  }
   374  
   375  // FilterByZone returns a slice containing all subnets that live in the availability zone specified.
   376  func (s Subnets) FilterByZone(zone string) (res Subnets) {
   377  	for _, x := range s {
   378  		if x.AvailabilityZone == zone {
   379  			res = append(res, x)
   380  		}
   381  	}
   382  	return
   383  }
   384  
   385  // GetUniqueZones returns a slice containing the unique zones of the subnets.
   386  func (s Subnets) GetUniqueZones() []string {
   387  	keys := make(map[string]bool)
   388  	zones := []string{}
   389  	for _, x := range s {
   390  		if _, value := keys[x.AvailabilityZone]; !value {
   391  			keys[x.AvailabilityZone] = true
   392  			zones = append(zones, x.AvailabilityZone)
   393  		}
   394  	}
   395  	return zones
   396  }
   397  
   398  // CNISpec defines configuration for CNI.
   399  type CNISpec struct {
   400  	// CNIIngressRules specify rules to apply to control plane and worker node security groups.
   401  	// The source for the rule will be set to control plane and worker security group IDs.
   402  	CNIIngressRules CNIIngressRules `json:"cniIngressRules,omitempty"`
   403  }
   404  
   405  // CNIIngressRules is a slice of CNIIngressRule
   406  type CNIIngressRules []CNIIngressRule
   407  
   408  // CNIIngressRule defines an AWS ingress rule for CNI requirements.
   409  type CNIIngressRule struct {
   410  	Description string                `json:"description"`
   411  	Protocol    SecurityGroupProtocol `json:"protocol"`
   412  	FromPort    int64                 `json:"fromPort"`
   413  	ToPort      int64                 `json:"toPort"`
   414  }
   415  
   416  // RouteTable defines an AWS routing table.
   417  type RouteTable struct {
   418  	ID string `json:"id"`
   419  }
   420  
   421  // SecurityGroupRole defines the unique role of a security group.
   422  type SecurityGroupRole string
   423  
   424  var (
   425  	// SecurityGroupBastion defines an SSH bastion role.
   426  	SecurityGroupBastion = SecurityGroupRole("bastion")
   427  
   428  	// SecurityGroupNode defines a Kubernetes workload node role.
   429  	SecurityGroupNode = SecurityGroupRole("node")
   430  
   431  	// SecurityGroupEKSNodeAdditional defines an extra node group from eks nodes.
   432  	SecurityGroupEKSNodeAdditional = SecurityGroupRole("node-eks-additional")
   433  
   434  	// SecurityGroupControlPlane defines a Kubernetes control plane node role.
   435  	SecurityGroupControlPlane = SecurityGroupRole("controlplane")
   436  
   437  	// SecurityGroupAPIServerLB defines a Kubernetes API Server Load Balancer role.
   438  	SecurityGroupAPIServerLB = SecurityGroupRole("apiserver-lb")
   439  
   440  	// SecurityGroupLB defines a container for the cloud provider to inject its load balancer ingress rules.
   441  	SecurityGroupLB = SecurityGroupRole("lb")
   442  )
   443  
   444  // SecurityGroup defines an AWS security group.
   445  type SecurityGroup struct {
   446  	// ID is a unique identifier.
   447  	ID string `json:"id"`
   448  
   449  	// Name is the security group name.
   450  	Name string `json:"name"`
   451  
   452  	// IngressRules is the inbound rules associated with the security group.
   453  	// +optional
   454  	IngressRules IngressRules `json:"ingressRule,omitempty"`
   455  
   456  	// Tags is a map of tags associated with the security group.
   457  	Tags Tags `json:"tags,omitempty"`
   458  }
   459  
   460  // String returns a string representation of the security group.
   461  func (s *SecurityGroup) String() string {
   462  	return fmt.Sprintf("id=%s/name=%s", s.ID, s.Name)
   463  }
   464  
   465  // SecurityGroupProtocol defines the protocol type for a security group rule.
   466  type SecurityGroupProtocol string
   467  
   468  var (
   469  	// SecurityGroupProtocolAll is a wildcard for all IP protocols.
   470  	SecurityGroupProtocolAll = SecurityGroupProtocol("-1")
   471  
   472  	// SecurityGroupProtocolIPinIP represents the IP in IP protocol in ingress rules.
   473  	SecurityGroupProtocolIPinIP = SecurityGroupProtocol("4")
   474  
   475  	// SecurityGroupProtocolTCP represents the TCP protocol in ingress rules.
   476  	SecurityGroupProtocolTCP = SecurityGroupProtocol("tcp")
   477  
   478  	// SecurityGroupProtocolUDP represents the UDP protocol in ingress rules.
   479  	SecurityGroupProtocolUDP = SecurityGroupProtocol("udp")
   480  
   481  	// SecurityGroupProtocolICMP represents the ICMP protocol in ingress rules.
   482  	SecurityGroupProtocolICMP = SecurityGroupProtocol("icmp")
   483  
   484  	// SecurityGroupProtocolICMPv6 represents the ICMPv6 protocol in ingress rules.
   485  	SecurityGroupProtocolICMPv6 = SecurityGroupProtocol("58")
   486  )
   487  
   488  // IngressRule defines an AWS ingress rule for security groups.
   489  type IngressRule struct {
   490  	Description string                `json:"description"`
   491  	Protocol    SecurityGroupProtocol `json:"protocol"`
   492  	FromPort    int64                 `json:"fromPort"`
   493  	ToPort      int64                 `json:"toPort"`
   494  
   495  	// List of CIDR blocks to allow access from. Cannot be specified with SourceSecurityGroupID.
   496  	// +optional
   497  	CidrBlocks []string `json:"cidrBlocks,omitempty"`
   498  
   499  	// The security group id to allow access from. Cannot be specified with CidrBlocks.
   500  	// +optional
   501  	SourceSecurityGroupIDs []string `json:"sourceSecurityGroupIds,omitempty"`
   502  }
   503  
   504  // String returns a string representation of the ingress rule.
   505  func (i *IngressRule) String() string {
   506  	return fmt.Sprintf("protocol=%s/range=[%d-%d]/description=%s", i.Protocol, i.FromPort, i.ToPort, i.Description)
   507  }
   508  
   509  // IngressRules is a slice of AWS ingress rules for security groups.
   510  type IngressRules []IngressRule
   511  
   512  // Difference returns the difference between this slice and the other slice.
   513  func (i IngressRules) Difference(o IngressRules) (out IngressRules) {
   514  	for index := range i {
   515  		x := i[index]
   516  		found := false
   517  		for oIndex := range o {
   518  			y := o[oIndex]
   519  			if x.Equals(&y) {
   520  				found = true
   521  				break
   522  			}
   523  		}
   524  
   525  		if !found {
   526  			out = append(out, x)
   527  		}
   528  	}
   529  
   530  	return
   531  }
   532  
   533  // Equals returns true if two IngressRule are equal.
   534  func (i *IngressRule) Equals(o *IngressRule) bool {
   535  	if len(i.CidrBlocks) != len(o.CidrBlocks) {
   536  		return false
   537  	}
   538  
   539  	sort.Strings(i.CidrBlocks)
   540  	sort.Strings(o.CidrBlocks)
   541  
   542  	for i, v := range i.CidrBlocks {
   543  		if v != o.CidrBlocks[i] {
   544  			return false
   545  		}
   546  	}
   547  
   548  	if len(i.SourceSecurityGroupIDs) != len(o.SourceSecurityGroupIDs) {
   549  		return false
   550  	}
   551  
   552  	sort.Strings(i.SourceSecurityGroupIDs)
   553  	sort.Strings(o.SourceSecurityGroupIDs)
   554  
   555  	for i, v := range i.SourceSecurityGroupIDs {
   556  		if v != o.SourceSecurityGroupIDs[i] {
   557  			return false
   558  		}
   559  	}
   560  
   561  	if i.Description != o.Description || i.Protocol != o.Protocol {
   562  		return false
   563  	}
   564  
   565  	// AWS seems to ignore the From/To port when set on protocols where it doesn't apply, but
   566  	// we avoid serializing it out for clarity's sake.
   567  	// See: https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_IpPermission.html
   568  	switch i.Protocol {
   569  	case SecurityGroupProtocolTCP,
   570  		SecurityGroupProtocolUDP,
   571  		SecurityGroupProtocolICMP,
   572  		SecurityGroupProtocolICMPv6:
   573  		return i.FromPort == o.FromPort && i.ToPort == o.ToPort
   574  	case SecurityGroupProtocolAll, SecurityGroupProtocolIPinIP:
   575  		// FromPort / ToPort are not applicable
   576  	}
   577  
   578  	return true
   579  }
   580  
   581  // InstanceState describes the state of an AWS instance.
   582  type InstanceState string
   583  
   584  var (
   585  	// InstanceStatePending is the string representing an instance in a pending state.
   586  	InstanceStatePending = InstanceState("pending")
   587  
   588  	// InstanceStateRunning is the string representing an instance in a running state.
   589  	InstanceStateRunning = InstanceState("running")
   590  
   591  	// InstanceStateShuttingDown is the string representing an instance shutting down.
   592  	InstanceStateShuttingDown = InstanceState("shutting-down")
   593  
   594  	// InstanceStateTerminated is the string representing an instance that has been terminated.
   595  	InstanceStateTerminated = InstanceState("terminated")
   596  
   597  	// InstanceStateStopping is the string representing an instance
   598  	// that is in the process of being stopped and can be restarted.
   599  	InstanceStateStopping = InstanceState("stopping")
   600  
   601  	// InstanceStateStopped is the string representing an instance
   602  	// that has been stopped and can be restarted.
   603  	InstanceStateStopped = InstanceState("stopped")
   604  
   605  	// InstanceRunningStates defines the set of states in which an EC2 instance is
   606  	// running or going to be running soon.
   607  	InstanceRunningStates = sets.NewString(
   608  		string(InstanceStatePending),
   609  		string(InstanceStateRunning),
   610  	)
   611  
   612  	// InstanceOperationalStates defines the set of states in which an EC2 instance is
   613  	// or can return to running, and supports all EC2 operations.
   614  	InstanceOperationalStates = InstanceRunningStates.Union(
   615  		sets.NewString(
   616  			string(InstanceStateStopping),
   617  			string(InstanceStateStopped),
   618  		),
   619  	)
   620  
   621  	// InstanceKnownStates represents all known EC2 instance states.
   622  	InstanceKnownStates = InstanceOperationalStates.Union(
   623  		sets.NewString(
   624  			string(InstanceStateShuttingDown),
   625  			string(InstanceStateTerminated),
   626  		),
   627  	)
   628  )
   629  
   630  // Instance describes an AWS instance.
   631  type Instance struct {
   632  	ID string `json:"id"`
   633  
   634  	// The current state of the instance.
   635  	State InstanceState `json:"instanceState,omitempty"`
   636  
   637  	// The instance type.
   638  	Type string `json:"type,omitempty"`
   639  
   640  	// The ID of the subnet of the instance.
   641  	SubnetID string `json:"subnetId,omitempty"`
   642  
   643  	// The ID of the AMI used to launch the instance.
   644  	ImageID string `json:"imageId,omitempty"`
   645  
   646  	// The name of the SSH key pair.
   647  	SSHKeyName *string `json:"sshKeyName,omitempty"`
   648  
   649  	// SecurityGroupIDs are one or more security group IDs this instance belongs to.
   650  	SecurityGroupIDs []string `json:"securityGroupIds,omitempty"`
   651  
   652  	// UserData is the raw data script passed to the instance which is run upon bootstrap.
   653  	// This field must not be base64 encoded and should only be used when running a new instance.
   654  	UserData *string `json:"userData,omitempty"`
   655  
   656  	// The name of the IAM instance profile associated with the instance, if applicable.
   657  	IAMProfile string `json:"iamProfile,omitempty"`
   658  
   659  	// Addresses contains the AWS instance associated addresses.
   660  	Addresses []clusterv1alpha4.MachineAddress `json:"addresses,omitempty"`
   661  
   662  	// The private IPv4 address assigned to the instance.
   663  	PrivateIP *string `json:"privateIp,omitempty"`
   664  
   665  	// The public IPv4 address assigned to the instance, if applicable.
   666  	PublicIP *string `json:"publicIp,omitempty"`
   667  
   668  	// Specifies whether enhanced networking with ENA is enabled.
   669  	ENASupport *bool `json:"enaSupport,omitempty"`
   670  
   671  	// Indicates whether the instance is optimized for Amazon EBS I/O.
   672  	EBSOptimized *bool `json:"ebsOptimized,omitempty"`
   673  
   674  	// Configuration options for the root storage volume.
   675  	// +optional
   676  	RootVolume *Volume `json:"rootVolume,omitempty"`
   677  
   678  	// Configuration options for the non root storage volumes.
   679  	// +optional
   680  	NonRootVolumes []Volume `json:"nonRootVolumes,omitempty"`
   681  
   682  	// Specifies ENIs attached to instance
   683  	NetworkInterfaces []string `json:"networkInterfaces,omitempty"`
   684  
   685  	// The tags associated with the instance.
   686  	Tags map[string]string `json:"tags,omitempty"`
   687  
   688  	// Availability zone of instance
   689  	AvailabilityZone string `json:"availabilityZone,omitempty"`
   690  
   691  	// SpotMarketOptions option for configuring instances to be run using AWS Spot instances.
   692  	SpotMarketOptions *SpotMarketOptions `json:"spotMarketOptions,omitempty"`
   693  
   694  	// Tenancy indicates if instance should run on shared or single-tenant hardware.
   695  	// +optional
   696  	Tenancy string `json:"tenancy,omitempty"`
   697  
   698  	// IDs of the instance's volumes
   699  	// +optional
   700  	VolumeIDs []string `json:"volumeIDs,omitempty"`
   701  }
   702  
   703  // Volume encapsulates the configuration options for the storage device
   704  type Volume struct {
   705  	// Device name
   706  	// +optional
   707  	DeviceName string `json:"deviceName,omitempty"`
   708  
   709  	// Size specifies size (in Gi) of the storage device.
   710  	// Must be greater than the image snapshot size or 8 (whichever is greater).
   711  	// +kubebuilder:validation:Minimum=8
   712  	Size int64 `json:"size"`
   713  
   714  	// Type is the type of the volume (e.g. gp2, io1, etc...).
   715  	// +optional
   716  	Type VolumeType `json:"type,omitempty"`
   717  
   718  	// IOPS is the number of IOPS requested for the disk. Not applicable to all types.
   719  	// +optional
   720  	IOPS int64 `json:"iops,omitempty"`
   721  
   722  	// Throughput to provision in MiB/s supported for the volume type. Not applicable to all types.
   723  	// +optional
   724  	Throughput *int64 `json:"throughput,omitempty"`
   725  
   726  	// Encrypted is whether the volume should be encrypted or not.
   727  	// +optional
   728  	Encrypted *bool `json:"encrypted,omitempty"`
   729  
   730  	// EncryptionKey is the KMS key to use to encrypt the volume. Can be either a KMS key ID or ARN.
   731  	// If Encrypted is set and this is omitted, the default AWS key will be used.
   732  	// The key must already exist and be accessible by the controller.
   733  	// +optional
   734  	EncryptionKey string `json:"encryptionKey,omitempty"`
   735  }
   736  
   737  // VolumeType describes the EBS volume type.
   738  // See: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volume-types.html
   739  type VolumeType string
   740  
   741  var (
   742  	// VolumeTypeIO1 is the string representing a provisioned iops ssd io1 volume
   743  	VolumeTypeIO1 = VolumeType("io1")
   744  
   745  	// VolumeTypeIO2 is the string representing a provisioned iops ssd io2 volume
   746  	VolumeTypeIO2 = VolumeType("io2")
   747  
   748  	// VolumeTypeGP2 is the string representing a general purpose ssd gp2 volume
   749  	VolumeTypeGP2 = VolumeType("gp2")
   750  
   751  	// VolumeTypeGP3 is the string representing a general purpose ssd gp3 volume
   752  	VolumeTypeGP3 = VolumeType("gp3")
   753  
   754  	// VolumeTypesGP are volume types provisioned for general purpose io
   755  	VolumeTypesGP = sets.NewString(
   756  		string(VolumeTypeIO1),
   757  		string(VolumeTypeIO2),
   758  	)
   759  
   760  	// VolumeTypesProvisioned are volume types provisioned for high performance io
   761  	VolumeTypesProvisioned = sets.NewString(
   762  		string(VolumeTypeIO1),
   763  		string(VolumeTypeIO2),
   764  	)
   765  )
   766  
   767  // SpotMarketOptions defines the options available to a user when configuring
   768  // Machines to run on Spot instances.
   769  // Most users should provide an empty struct.
   770  type SpotMarketOptions struct {
   771  	// MaxPrice defines the maximum price the user is willing to pay for Spot VM instances
   772  	// +optional
   773  	// +kubebuilder:validation:pattern="^[0-9]+(\.[0-9]+)?$"
   774  	MaxPrice *string `json:"maxPrice,omitempty"`
   775  }
   776  
   777  // EKSAMILookupType specifies which AWS AMI to use for a AWSMachine and AWSMachinePool.
   778  type EKSAMILookupType string
   779  
   780  const (
   781  	// AmazonLinux is the default AMI type.
   782  	AmazonLinux EKSAMILookupType = "AmazonLinux"
   783  	// AmazonLinuxGPU is the AmazonLinux GPU AMI type.
   784  	AmazonLinuxGPU EKSAMILookupType = "AmazonLinuxGPU"
   785  )