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

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