diff --git a/Makefile b/Makefile
index 608bd1704..eeca07bb4 100644
--- a/Makefile
+++ b/Makefile
@@ -21,9 +21,15 @@ AWS_SDK_MODEL_OVERRIDE ?= "n"
# Move Gateway API CRDs from bases directory to gateway directory
MOVE_GATEWAY_CRDS = mv config/crd/bases/gateway.k8s.aws_* config/crd/gateway/
+# Move AGA CRDs from bases directory to aga directory
+MOVE_AGA_CRDS = mkdir -p config/crd/aga && mv config/crd/bases/aga.k8s.aws_* config/crd/aga/
+
# Copy combined Gateway API CRDs from bases directory to helm directory
COPY_GATEWAY_CRDS_TO_HELM = cp config/crd/gateway/gateway-crds.yaml helm/aws-load-balancer-controller/crds/gateway-crds.yaml
+# Copy combined AGA CRDs from aga directory to helm directory
+COPY_AGA_CRDS_TO_HELM = cp config/crd/aga/aga-crds.yaml helm/aws-load-balancer-controller/crds/aga-crds.yaml
+
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
GOBIN=$(shell go env GOPATH)/bin
@@ -68,11 +74,16 @@ manifests: controller-gen kustomize
crds: manifests
$(MOVE_GATEWAY_CRDS)
+ $(MOVE_AGA_CRDS)
$(KUSTOMIZE) build config/crd > helm/aws-load-balancer-controller/crds/crds.yaml
$(KUSTOMIZE) build config/crd/gateway > config/crd/gateway/gateway-crds.yaml
echo '---' > config/crd/gateway/gateway-crds.yaml
$(KUSTOMIZE) build config/crd/gateway >> config/crd/gateway/gateway-crds.yaml
$(COPY_GATEWAY_CRDS_TO_HELM)
+ $(KUSTOMIZE) build config/crd/aga > config/crd/aga/aga-crds.yaml
+ echo '---' > config/crd/aga/aga-crds.yaml
+ $(KUSTOMIZE) build config/crd/aga >> config/crd/aga/aga-crds.yaml
+ $(COPY_AGA_CRDS_TO_HELM)
# Run go fmt against code
fmt:
@@ -218,3 +229,12 @@ gw-api-ref-docs:
--config=crd-ref-docs.yaml \
--renderer=markdown \
--output-path=${PWD}/docs/guide/gateway/spec.md
+
+# generate aga CRD spec doc
+.PHONY: aga-ref-docs
+aga-ref-docs:
+ crd-ref-docs \
+ --source-path=${PWD}/apis/aga/ \
+ --config=crd-ref-docs.yaml \
+ --renderer=markdown \
+ --output-path=${PWD}/docs/guide/globalaccelerator/spec.md
diff --git a/apis/aga/v1beta1/globalaccelerator_types.go b/apis/aga/v1beta1/globalaccelerator_types.go
new file mode 100644
index 000000000..55bb619a5
--- /dev/null
+++ b/apis/aga/v1beta1/globalaccelerator_types.go
@@ -0,0 +1,306 @@
+/*
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1beta1
+
+import (
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// +kubebuilder:validation:Enum=TCP;UDP
+// GlobalAcceleratorProtocol defines the protocol for Global Accelerator listeners.
+type GlobalAcceleratorProtocol string
+
+const (
+ GlobalAcceleratorProtocolTCP GlobalAcceleratorProtocol = "TCP"
+ GlobalAcceleratorProtocolUDP GlobalAcceleratorProtocol = "UDP"
+)
+
+// +kubebuilder:validation:Enum=SOURCE_IP;NONE
+// ClientAffinityType defines the client affinity for Global Accelerator listeners.
+type ClientAffinityType string
+
+const (
+ ClientAffinitySourceIP ClientAffinityType = "SOURCE_IP"
+ ClientAffinityNone ClientAffinityType = "NONE"
+)
+
+// +kubebuilder:validation:Enum=IPV4;DUAL_STACK
+// IPAddressType defines the IP address type for Global Accelerator.
+type IPAddressType string
+
+const (
+ IPAddressTypeIPV4 IPAddressType = "IPV4"
+ IPAddressTypeDualStack IPAddressType = "DUAL_STACK"
+)
+
+// PortRange defines the port range for Global Accelerator listeners.
+type PortRange struct {
+ // FromPort is the first port in the range of ports, inclusive.
+ // +kubebuilder:validation:Minimum=1
+ // +kubebuilder:validation:Maximum=65535
+ FromPort int32 `json:"fromPort"`
+
+ // ToPort is the last port in the range of ports, inclusive.
+ // +kubebuilder:validation:Minimum=1
+ // +kubebuilder:validation:Maximum=65535
+ ToPort int32 `json:"toPort"`
+}
+
+// GlobalAcceleratorListener defines a listener for the Global Accelerator.
+type GlobalAcceleratorListener struct {
+ // Protocol is the protocol for the connections from clients to the accelerator.
+ // When not specified, the controller will automatically determine the protocol by inspecting
+ // the referenced Kubernetes resources (Service, Ingress, or Gateway) in the endpoint groups.
+ // +optional
+ Protocol *GlobalAcceleratorProtocol `json:"protocol,omitempty"`
+
+ // PortRanges is the list of port ranges for the connections from clients to the accelerator.
+ // When not specified, the controller will automatically determine the port ranges by inspecting
+ // the referenced Kubernetes resources (Service, Ingress, or Gateway) in the endpoint groups.
+ // +kubebuilder:validation:MinItems=1
+ // +kubebuilder:validation:MaxItems=10
+ // +optional
+ PortRanges *[]PortRange `json:"portRanges,omitempty"`
+
+ // ClientAffinity lets you direct all requests from a user to the same endpoint, if you have stateful applications, regardless of the port and protocol of the client request.
+ // Client affinity gives you control over whether to always route each client to the same specific endpoint.
+ // AWS Global Accelerator uses a consistent-flow hashing algorithm to choose the optimal endpoint for a connection.
+ // If client affinity is NONE, Global Accelerator uses the "five-tuple" (5-tuple) properties—source IP address, source port, destination IP address, destination port, and protocol—to select the hash value, and then chooses the best endpoint.
+ // However, with this setting, if someone uses different ports to connect to Global Accelerator, their connections might not be always routed to the same endpoint because the hash value changes.
+ // If you want a given client to always be routed to the same endpoint, set client affinity to SOURCE_IP instead.
+ // When you use the SOURCE_IP setting, Global Accelerator uses the "two-tuple" (2-tuple) properties— source (client) IP address and destination IP address—to select the hash value.
+ // The default value is NONE.
+ // +kubebuilder:default="NONE"
+ // +optional
+ ClientAffinity ClientAffinityType `json:"clientAffinity,omitempty"`
+
+ // EndpointGroups defines a list of endpoint groups for a Global Accelerator listener.
+ // +optional
+ EndpointGroups *[]GlobalAcceleratorEndpointGroup `json:"endpointGroups,omitempty"`
+}
+
+// GlobalAcceleratorEndpointGroup defines an endpoint group for a Global Accelerator listener.
+type GlobalAcceleratorEndpointGroup struct {
+ // Region is the AWS Region where the endpoint group is located.
+ // If unspecified, defaults to the current cluster region.
+ // +kubebuilder:validation:MaxLength=255
+ // +optional
+ Region *string `json:"region,omitempty"`
+
+ // TrafficDialPercentage is the percentage of traffic to send to an AWS Regions. Additional traffic is distributed to other endpoint groups for this listener
+ // Use this action to increase (dial up) or decrease (dial down) traffic to a specific Region. The percentage is applied to the traffic that would otherwise have been routed to the Region based on optimal routing.
+ // +kubebuilder:validation:Minimum=0
+ // +kubebuilder:validation:Maximum=100
+ // +kubebuilder:default=100
+ // +optional
+ TrafficDialPercentage *int32 `json:"trafficDialPercentage,omitempty"`
+
+ // PortOverrides is a list of endpoint port overrides. Allows you to override the destination ports used to route traffic to an endpoint. Using a port override lets you map a list of external destination ports (that your users send traffic to) to a list of internal destination ports that you want an application endpoint to receive traffic on.
+ // +optional
+ PortOverrides *[]PortOverride `json:"portOverrides,omitempty"`
+
+ // Endpoints is the list of endpoint configurations for this endpoint group.
+ // +optional
+ Endpoints *[]GlobalAcceleratorEndpoint `json:"endpoints,omitempty"`
+}
+
+// PortOverride defines a port override for an endpoint group.
+// Override specific listener ports used to route traffic to endpoints that are part of an endpoint group.
+// For example, you can create a port override in which the listener receives user traffic on ports 80 and 443,
+// but your accelerator routes that traffic to ports 1080 and 1443, respectively, on the endpoints.
+//
+// For more information, see Port overrides in the AWS Global Accelerator Developer Guide:
+// https://docs.aws.amazon.com/global-accelerator/latest/dg/about-endpoint-groups-port-override.html
+type PortOverride struct {
+ // ListenerPort is the listener port that you want to map to a specific endpoint port.
+ // This is the port that user traffic arrives to the Global Accelerator on.
+ // +kubebuilder:validation:Minimum=1
+ // +kubebuilder:validation:Maximum=65535
+ ListenerPort int32 `json:"listenerPort"`
+
+ // EndpointPort is the endpoint port that you want traffic to be routed to.
+ // This is the port on the endpoint, such as the Application Load Balancer or Amazon EC2 instance.
+ // +kubebuilder:validation:Minimum=1
+ // +kubebuilder:validation:Maximum=65535
+ EndpointPort int32 `json:"endpointPort"`
+}
+
+// +kubebuilder:validation:Enum=EndpointID;Service;Ingress;Gateway
+// GlobalAcceleratorEndpointType defines the type of endpoint for Global Accelerator.
+type GlobalAcceleratorEndpointType string
+
+const (
+ GlobalAcceleratorEndpointTypeEndpointID GlobalAcceleratorEndpointType = "EndpointID"
+ GlobalAcceleratorEndpointTypeService GlobalAcceleratorEndpointType = "Service"
+ GlobalAcceleratorEndpointTypeIngress GlobalAcceleratorEndpointType = "Ingress"
+ GlobalAcceleratorEndpointTypeGateway GlobalAcceleratorEndpointType = "Gateway"
+)
+
+// GlobalAcceleratorEndpoint defines an endpoint for a Global Accelerator endpoint group.
+// +kubebuilder:validation:XValidation:rule="self.type != 'EndpointID' || (has(self.endpointID) && !has(self.name))",message="endpointID is required and name must not be set when type is EndpointID"
+// +kubebuilder:validation:XValidation:rule="self.type == 'EndpointID' || (has(self.name) && !has(self.endpointID))",message="name is required and endpointID must not be set when type is Service/Ingress/Gateway"
+type GlobalAcceleratorEndpoint struct {
+ // Type specifies the type of endpoint reference.
+ Type GlobalAcceleratorEndpointType `json:"type"`
+
+ // EndpointID is the ID of the endpoint when type is EndpointID.
+ // If the endpoint is a Network Load Balancer or Application Load Balancer, this is the Amazon Resource Name (ARN) of the resource.
+ // A resource must be valid and active when you add it as an endpoint.
+ // Mandatory for remote regions.
+ // +kubebuilder:validation:MaxLength=255
+ // +optional
+ EndpointID *string `json:"endpointID,omitempty"`
+
+ // Name is the name of the Kubernetes resource when type is Service, Ingress, or Gateway.
+ // +optional
+ Name *string `json:"name,omitempty"`
+
+ // Namespace is the namespace of the Kubernetes resource when type is Service, Ingress, or Gateway.
+ // If not specified, defaults to the same namespace as the GlobalAccelerator resource.
+ // +optional
+ Namespace *string `json:"namespace,omitempty"`
+
+ // Weight is the weight associated with the endpoint. When you add weights to endpoints, you configure Global Accelerator to route traffic based on proportions that you specify.
+ // For example, you might specify endpoint weights of 4, 5, 5, and 6 (sum=20). The result is that 4/20 of your traffic, on average, is routed to the first endpoint,
+ // 5/20 is routed both to the second and third endpoints, and 6/20 is routed to the last endpoint.
+ // For more information, see Endpoint Weights in the AWS Global Accelerator Developer Guide:
+ // https://docs.aws.amazon.com/global-accelerator/latest/dg/about-endpoints-endpoint-weights.html
+ // +kubebuilder:validation:Minimum=0
+ // +kubebuilder:validation:Maximum=255
+ // +kubebuilder:default=128
+ // +optional
+ Weight *int32 `json:"weight,omitempty"`
+
+ // ClientIPPreservationEnabled indicates whether client IP address preservation is enabled for an Application Load Balancer endpoint.
+ // The value is true or false. The default value is true for new accelerators.
+ // If the value is set to true, the client's IP address is preserved in the X-Forwarded-For request header as traffic travels to applications on the Application Load Balancer endpoint fronted by the accelerator.
+ // For more information, see Preserve Client IP Addresses in the AWS Global Accelerator Developer Guide:
+ // https://docs.aws.amazon.com/global-accelerator/latest/dg/preserve-client-ip-address.html
+ // +kubebuilder:default=true
+ // +optional
+ ClientIPPreservationEnabled *bool `json:"clientIPPreservationEnabled,omitempty"`
+}
+
+// GlobalAcceleratorSpec defines the desired state of GlobalAccelerator
+type GlobalAcceleratorSpec struct {
+ // Name is the name of the Global Accelerator.
+ // The name must contain only alphanumeric characters or hyphens (-), and must not begin or end with a hyphen.
+ // +kubebuilder:validation:Pattern="^[a-zA-Z0-9_-]{1,64}$"
+ // +kubebuilder:validation:MinLength=1
+ // +kubebuilder:validation:MaxLength=64
+ // +optional
+ Name *string `json:"name,omitempty"`
+
+ // IpAddresses optionally specifies the IP addresses from your own IP address pool (BYOIP) to use for the accelerator's static IP addresses.
+ // You can specify one or two addresses. Do not include the /32 suffix.
+ // If you bring your own IP address pool to Global Accelerator (BYOIP), you can choose an IPv4 address from your own pool to use for the accelerator's static IPv4 address.
+ // After you bring an address range to AWS, it appears in your account as an address pool. When you create an accelerator, you can assign one IPv4 address from your range to it.
+ // Global Accelerator assigns you a second static IPv4 address from an Amazon IP address range. If you bring two IPv4 address ranges to AWS, you can assign one IPv4 address from each range to your accelerator.
+ // Note that you can't update IP addresses for an existing accelerator. To change them, you must create a new accelerator with the new addresses.
+ // For more information, see Bring your own IP addresses (BYOIP) in the AWS Global Accelerator Developer Guide.
+ // https://docs.aws.amazon.com/global-accelerator/latest/dg/using-byoip.html
+ // +kubebuilder:validation:MinItems=1
+ // +kubebuilder:validation:MaxItems=2
+ // +optional
+ IpAddresses *[]string `json:"ipAddresses,omitempty"`
+
+ // IPAddressType is the value for the address type.
+ // +kubebuilder:default="IPV4"
+ // +optional
+ IPAddressType IPAddressType `json:"ipAddressType,omitempty"`
+
+ // Tags defines list of Tags on the Global Accelerator.
+ // +optional
+ Tags *map[string]string `json:"tags,omitempty"`
+
+ // Listeners defines the listeners for the Global Accelerator.
+ // +optional
+ Listeners *[]GlobalAcceleratorListener `json:"listeners,omitempty"`
+}
+
+// GlobalAcceleratorStatus defines the observed state of GlobalAccelerator
+type GlobalAcceleratorStatus struct {
+ // The generation observed by the GlobalAccelerator controller.
+ // +optional
+ ObservedGeneration *int64 `json:"observedGeneration,omitempty"`
+
+ // AcceleratorARN is the Amazon Resource Name (ARN) of the accelerator.
+ // +optional
+ AcceleratorARN *string `json:"acceleratorARN,omitempty"`
+
+ // DNSName The Domain Name System (DNS) name that Global Accelerator creates that points to an accelerator's static IPv4 addresses.
+ // +optional
+ DNSName *string `json:"dnsName,omitempty"`
+
+ // DualStackDnsName is the Domain Name System (DNS) name that Global Accelerator creates that points to a dual-stack accelerator's four static IP addresses: two IPv4 addresses and two IPv6 addresses.
+ // +optional
+ DualStackDnsName *string `json:"dualStackDnsName,omitempty"`
+
+ // IPSets is the static IP addresses that Global Accelerator associates with the accelerator.
+ // +optional
+ IPSets []IPSet `json:"ipSets,omitempty"`
+
+ // Status is the current status of the accelerator.
+ // +optional
+ Status *string `json:"status,omitempty"`
+
+ // Conditions represent the current conditions of the GlobalAccelerator.
+ // +optional
+ Conditions []metav1.Condition `json:"conditions,omitempty"`
+}
+
+// IPSet is the static IP addresses that Global Accelerator associates with the accelerator.
+type IPSet struct {
+
+ // IpAddresses is the array of IP addresses in the IP address set.
+ // +optional
+ IpAddresses *[]string `json:"ipAddresses,omitempty"`
+
+ // IpAddressFamily is the types of IP addresses included in this IP set.
+ // +optional
+ IpAddressFamily *string `json:"ipAddressFamily,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+// +kubebuilder:subresource:status
+// +kubebuilder:storageversion
+// +kubebuilder:printcolumn:name="NAME",type="string",JSONPath=".spec.name",description="The Global Accelerator name"
+// +kubebuilder:printcolumn:name="DNS-NAME",type="string",JSONPath=".status.dnsName",description="The Global Accelerator DNS name"
+// +kubebuilder:printcolumn:name="TYPE",type="string",JSONPath=".spec.type",description="The Global Accelerator type"
+// +kubebuilder:printcolumn:name="STATUS",type="string",JSONPath=".status.status",description="The Global Accelerator status"
+// +kubebuilder:printcolumn:name="ARN",type="string",JSONPath=".status.acceleratorARN",description="The Global Accelerator ARN",priority=1
+// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
+// GlobalAccelerator is the Schema for the GlobalAccelerator API
+type GlobalAccelerator struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+
+ Spec GlobalAcceleratorSpec `json:"spec,omitempty"`
+ Status GlobalAcceleratorStatus `json:"status,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+// GlobalAcceleratorList contains a list of GlobalAccelerator
+type GlobalAcceleratorList struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ListMeta `json:"metadata,omitempty"`
+ Items []GlobalAccelerator `json:"items"`
+}
+
+func init() {
+ SchemeBuilder.Register(&GlobalAccelerator{}, &GlobalAcceleratorList{})
+}
diff --git a/apis/aga/v1beta1/groupversion_info.go b/apis/aga/v1beta1/groupversion_info.go
new file mode 100644
index 000000000..5a3583a52
--- /dev/null
+++ b/apis/aga/v1beta1/groupversion_info.go
@@ -0,0 +1,36 @@
+/*
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Package v1beta1 contains API Schema definitions for the aga v1beta1 API group
+// +kubebuilder:object:generate=true
+// +groupName=aga.k8s.aws
+package v1beta1
+
+import (
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "sigs.k8s.io/controller-runtime/pkg/scheme"
+)
+
+var (
+ // GroupVersion is group version used to register these objects
+ GroupVersion = schema.GroupVersion{Group: "aga.k8s.aws", Version: "v1beta1"}
+
+ // SchemeBuilder is used to add go types to the GroupVersionKind scheme
+ SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
+
+ // AddToScheme adds the types in this group-version to the given scheme.
+ AddToScheme = SchemeBuilder.AddToScheme
+)
diff --git a/apis/aga/v1beta1/zz_generated.deepcopy.go b/apis/aga/v1beta1/zz_generated.deepcopy.go
new file mode 100644
index 000000000..220204910
--- /dev/null
+++ b/apis/aga/v1beta1/zz_generated.deepcopy.go
@@ -0,0 +1,374 @@
+//go:build !ignore_autogenerated
+
+/*
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by controller-gen. DO NOT EDIT.
+
+package v1beta1
+
+import (
+ "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+)
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GlobalAccelerator) DeepCopyInto(out *GlobalAccelerator) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ in.Spec.DeepCopyInto(&out.Spec)
+ in.Status.DeepCopyInto(&out.Status)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalAccelerator.
+func (in *GlobalAccelerator) DeepCopy() *GlobalAccelerator {
+ if in == nil {
+ return nil
+ }
+ out := new(GlobalAccelerator)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *GlobalAccelerator) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GlobalAcceleratorEndpoint) DeepCopyInto(out *GlobalAcceleratorEndpoint) {
+ *out = *in
+ if in.EndpointID != nil {
+ in, out := &in.EndpointID, &out.EndpointID
+ *out = new(string)
+ **out = **in
+ }
+ if in.Name != nil {
+ in, out := &in.Name, &out.Name
+ *out = new(string)
+ **out = **in
+ }
+ if in.Namespace != nil {
+ in, out := &in.Namespace, &out.Namespace
+ *out = new(string)
+ **out = **in
+ }
+ if in.Weight != nil {
+ in, out := &in.Weight, &out.Weight
+ *out = new(int32)
+ **out = **in
+ }
+ if in.ClientIPPreservationEnabled != nil {
+ in, out := &in.ClientIPPreservationEnabled, &out.ClientIPPreservationEnabled
+ *out = new(bool)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalAcceleratorEndpoint.
+func (in *GlobalAcceleratorEndpoint) DeepCopy() *GlobalAcceleratorEndpoint {
+ if in == nil {
+ return nil
+ }
+ out := new(GlobalAcceleratorEndpoint)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GlobalAcceleratorEndpointGroup) DeepCopyInto(out *GlobalAcceleratorEndpointGroup) {
+ *out = *in
+ if in.Region != nil {
+ in, out := &in.Region, &out.Region
+ *out = new(string)
+ **out = **in
+ }
+ if in.TrafficDialPercentage != nil {
+ in, out := &in.TrafficDialPercentage, &out.TrafficDialPercentage
+ *out = new(int32)
+ **out = **in
+ }
+ if in.PortOverrides != nil {
+ in, out := &in.PortOverrides, &out.PortOverrides
+ *out = new([]PortOverride)
+ if **in != nil {
+ in, out := *in, *out
+ *out = make([]PortOverride, len(*in))
+ copy(*out, *in)
+ }
+ }
+ if in.Endpoints != nil {
+ in, out := &in.Endpoints, &out.Endpoints
+ *out = new([]GlobalAcceleratorEndpoint)
+ if **in != nil {
+ in, out := *in, *out
+ *out = make([]GlobalAcceleratorEndpoint, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalAcceleratorEndpointGroup.
+func (in *GlobalAcceleratorEndpointGroup) DeepCopy() *GlobalAcceleratorEndpointGroup {
+ if in == nil {
+ return nil
+ }
+ out := new(GlobalAcceleratorEndpointGroup)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GlobalAcceleratorList) DeepCopyInto(out *GlobalAcceleratorList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]GlobalAccelerator, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalAcceleratorList.
+func (in *GlobalAcceleratorList) DeepCopy() *GlobalAcceleratorList {
+ if in == nil {
+ return nil
+ }
+ out := new(GlobalAcceleratorList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *GlobalAcceleratorList) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GlobalAcceleratorListener) DeepCopyInto(out *GlobalAcceleratorListener) {
+ *out = *in
+ if in.Protocol != nil {
+ in, out := &in.Protocol, &out.Protocol
+ *out = new(GlobalAcceleratorProtocol)
+ **out = **in
+ }
+ if in.PortRanges != nil {
+ in, out := &in.PortRanges, &out.PortRanges
+ *out = new([]PortRange)
+ if **in != nil {
+ in, out := *in, *out
+ *out = make([]PortRange, len(*in))
+ copy(*out, *in)
+ }
+ }
+ if in.EndpointGroups != nil {
+ in, out := &in.EndpointGroups, &out.EndpointGroups
+ *out = new([]GlobalAcceleratorEndpointGroup)
+ if **in != nil {
+ in, out := *in, *out
+ *out = make([]GlobalAcceleratorEndpointGroup, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalAcceleratorListener.
+func (in *GlobalAcceleratorListener) DeepCopy() *GlobalAcceleratorListener {
+ if in == nil {
+ return nil
+ }
+ out := new(GlobalAcceleratorListener)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GlobalAcceleratorSpec) DeepCopyInto(out *GlobalAcceleratorSpec) {
+ *out = *in
+ if in.Name != nil {
+ in, out := &in.Name, &out.Name
+ *out = new(string)
+ **out = **in
+ }
+ if in.IpAddresses != nil {
+ in, out := &in.IpAddresses, &out.IpAddresses
+ *out = new([]string)
+ if **in != nil {
+ in, out := *in, *out
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+ }
+ if in.Tags != nil {
+ in, out := &in.Tags, &out.Tags
+ *out = new(map[string]string)
+ if **in != nil {
+ in, out := *in, *out
+ *out = make(map[string]string, len(*in))
+ for key, val := range *in {
+ (*out)[key] = val
+ }
+ }
+ }
+ if in.Listeners != nil {
+ in, out := &in.Listeners, &out.Listeners
+ *out = new([]GlobalAcceleratorListener)
+ if **in != nil {
+ in, out := *in, *out
+ *out = make([]GlobalAcceleratorListener, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalAcceleratorSpec.
+func (in *GlobalAcceleratorSpec) DeepCopy() *GlobalAcceleratorSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(GlobalAcceleratorSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GlobalAcceleratorStatus) DeepCopyInto(out *GlobalAcceleratorStatus) {
+ *out = *in
+ if in.ObservedGeneration != nil {
+ in, out := &in.ObservedGeneration, &out.ObservedGeneration
+ *out = new(int64)
+ **out = **in
+ }
+ if in.AcceleratorARN != nil {
+ in, out := &in.AcceleratorARN, &out.AcceleratorARN
+ *out = new(string)
+ **out = **in
+ }
+ if in.DNSName != nil {
+ in, out := &in.DNSName, &out.DNSName
+ *out = new(string)
+ **out = **in
+ }
+ if in.DualStackDnsName != nil {
+ in, out := &in.DualStackDnsName, &out.DualStackDnsName
+ *out = new(string)
+ **out = **in
+ }
+ if in.IPSets != nil {
+ in, out := &in.IPSets, &out.IPSets
+ *out = make([]IPSet, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.Status != nil {
+ in, out := &in.Status, &out.Status
+ *out = new(string)
+ **out = **in
+ }
+ if in.Conditions != nil {
+ in, out := &in.Conditions, &out.Conditions
+ *out = make([]v1.Condition, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalAcceleratorStatus.
+func (in *GlobalAcceleratorStatus) DeepCopy() *GlobalAcceleratorStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(GlobalAcceleratorStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IPSet) DeepCopyInto(out *IPSet) {
+ *out = *in
+ if in.IpAddresses != nil {
+ in, out := &in.IpAddresses, &out.IpAddresses
+ *out = new([]string)
+ if **in != nil {
+ in, out := *in, *out
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+ }
+ if in.IpAddressFamily != nil {
+ in, out := &in.IpAddressFamily, &out.IpAddressFamily
+ *out = new(string)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPSet.
+func (in *IPSet) DeepCopy() *IPSet {
+ if in == nil {
+ return nil
+ }
+ out := new(IPSet)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PortOverride) DeepCopyInto(out *PortOverride) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PortOverride.
+func (in *PortOverride) DeepCopy() *PortOverride {
+ if in == nil {
+ return nil
+ }
+ out := new(PortOverride)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PortRange) DeepCopyInto(out *PortRange) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PortRange.
+func (in *PortRange) DeepCopy() *PortRange {
+ if in == nil {
+ return nil
+ }
+ out := new(PortRange)
+ in.DeepCopyInto(out)
+ return out
+}
diff --git a/config/crd/aga/aga-crds.yaml b/config/crd/aga/aga-crds.yaml
new file mode 100644
index 000000000..adad811f7
--- /dev/null
+++ b/config/crd/aga/aga-crds.yaml
@@ -0,0 +1,414 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.14.0
+ name: globalaccelerators.aga.k8s.aws
+spec:
+ group: aga.k8s.aws
+ names:
+ kind: GlobalAccelerator
+ listKind: GlobalAcceleratorList
+ plural: globalaccelerators
+ singular: globalaccelerator
+ scope: Namespaced
+ versions:
+ - additionalPrinterColumns:
+ - description: The Global Accelerator name
+ jsonPath: .spec.name
+ name: NAME
+ type: string
+ - description: The Global Accelerator DNS name
+ jsonPath: .status.dnsName
+ name: DNS-NAME
+ type: string
+ - description: The Global Accelerator type
+ jsonPath: .spec.type
+ name: TYPE
+ type: string
+ - description: The Global Accelerator status
+ jsonPath: .status.status
+ name: STATUS
+ type: string
+ - description: The Global Accelerator ARN
+ jsonPath: .status.acceleratorARN
+ name: ARN
+ priority: 1
+ type: string
+ - jsonPath: .metadata.creationTimestamp
+ name: AGE
+ type: date
+ name: v1beta1
+ schema:
+ openAPIV3Schema:
+ description: GlobalAccelerator is the Schema for the GlobalAccelerator API
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: GlobalAcceleratorSpec defines the desired state of GlobalAccelerator
+ properties:
+ ipAddressType:
+ default: IPV4
+ description: IPAddressType is the value for the address type.
+ enum:
+ - IPV4
+ - DUAL_STACK
+ type: string
+ ipAddresses:
+ description: |-
+ IpAddresses optionally specifies the IP addresses from your own IP address pool (BYOIP) to use for the accelerator's static IP addresses.
+ You can specify one or two addresses. Do not include the /32 suffix.
+ If you bring your own IP address pool to Global Accelerator (BYOIP), you can choose an IPv4 address from your own pool to use for the accelerator's static IPv4 address.
+ After you bring an address range to AWS, it appears in your account as an address pool. When you create an accelerator, you can assign one IPv4 address from your range to it.
+ Global Accelerator assigns you a second static IPv4 address from an Amazon IP address range. If you bring two IPv4 address ranges to AWS, you can assign one IPv4 address from each range to your accelerator.
+ Note that you can't update IP addresses for an existing accelerator. To change them, you must create a new accelerator with the new addresses.
+ For more information, see Bring your own IP addresses (BYOIP) in the AWS Global Accelerator Developer Guide.
+ https://docs.aws.amazon.com/global-accelerator/latest/dg/using-byoip.html
+ items:
+ type: string
+ maxItems: 2
+ minItems: 1
+ type: array
+ listeners:
+ description: Listeners defines the listeners for the Global Accelerator.
+ items:
+ description: GlobalAcceleratorListener defines a listener for the
+ Global Accelerator.
+ properties:
+ clientAffinity:
+ default: NONE
+ description: |-
+ ClientAffinity lets you direct all requests from a user to the same endpoint, if you have stateful applications, regardless of the port and protocol of the client request.
+ Client affinity gives you control over whether to always route each client to the same specific endpoint.
+ AWS Global Accelerator uses a consistent-flow hashing algorithm to choose the optimal endpoint for a connection.
+ If client affinity is NONE, Global Accelerator uses the "five-tuple" (5-tuple) properties—source IP address, source port, destination IP address, destination port, and protocol—to select the hash value, and then chooses the best endpoint.
+ However, with this setting, if someone uses different ports to connect to Global Accelerator, their connections might not be always routed to the same endpoint because the hash value changes.
+ If you want a given client to always be routed to the same endpoint, set client affinity to SOURCE_IP instead.
+ When you use the SOURCE_IP setting, Global Accelerator uses the "two-tuple" (2-tuple) properties— source (client) IP address and destination IP address—to select the hash value.
+ The default value is NONE.
+ enum:
+ - SOURCE_IP
+ - NONE
+ type: string
+ endpointGroups:
+ description: EndpointGroups defines a list of endpoint groups
+ for a Global Accelerator listener.
+ items:
+ description: GlobalAcceleratorEndpointGroup defines an endpoint
+ group for a Global Accelerator listener.
+ properties:
+ endpoints:
+ description: Endpoints is the list of endpoint configurations
+ for this endpoint group.
+ items:
+ description: GlobalAcceleratorEndpoint defines an endpoint
+ for a Global Accelerator endpoint group.
+ properties:
+ clientIPPreservationEnabled:
+ default: true
+ description: |-
+ ClientIPPreservationEnabled indicates whether client IP address preservation is enabled for an Application Load Balancer endpoint.
+ The value is true or false. The default value is true for new accelerators.
+ If the value is set to true, the client's IP address is preserved in the X-Forwarded-For request header as traffic travels to applications on the Application Load Balancer endpoint fronted by the accelerator.
+ For more information, see Preserve Client IP Addresses in the AWS Global Accelerator Developer Guide:
+ https://docs.aws.amazon.com/global-accelerator/latest/dg/preserve-client-ip-address.html
+ type: boolean
+ endpointID:
+ description: |-
+ EndpointID is the ID of the endpoint when type is EndpointID.
+ If the endpoint is a Network Load Balancer or Application Load Balancer, this is the Amazon Resource Name (ARN) of the resource.
+ A resource must be valid and active when you add it as an endpoint.
+ Mandatory for remote regions.
+ maxLength: 255
+ type: string
+ name:
+ description: Name is the name of the Kubernetes
+ resource when type is Service, Ingress, or Gateway.
+ type: string
+ namespace:
+ description: |-
+ Namespace is the namespace of the Kubernetes resource when type is Service, Ingress, or Gateway.
+ If not specified, defaults to the same namespace as the GlobalAccelerator resource.
+ type: string
+ type:
+ description: Type specifies the type of endpoint
+ reference.
+ enum:
+ - EndpointID
+ - Service
+ - Ingress
+ - Gateway
+ type: string
+ weight:
+ default: 128
+ description: |-
+ Weight is the weight associated with the endpoint. When you add weights to endpoints, you configure Global Accelerator to route traffic based on proportions that you specify.
+ For example, you might specify endpoint weights of 4, 5, 5, and 6 (sum=20). The result is that 4/20 of your traffic, on average, is routed to the first endpoint,
+ 5/20 is routed both to the second and third endpoints, and 6/20 is routed to the last endpoint.
+ For more information, see Endpoint Weights in the AWS Global Accelerator Developer Guide:
+ https://docs.aws.amazon.com/global-accelerator/latest/dg/about-endpoints-endpoint-weights.html
+ format: int32
+ maximum: 255
+ minimum: 0
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: endpointID is required and name must not
+ be set when type is EndpointID
+ rule: self.type != 'EndpointID' || (has(self.endpointID)
+ && !has(self.name))
+ - message: name is required and endpointID must not
+ be set when type is Service/Ingress/Gateway
+ rule: self.type == 'EndpointID' || (has(self.name)
+ && !has(self.endpointID))
+ type: array
+ portOverrides:
+ description: PortOverrides is a list of endpoint port
+ overrides. Allows you to override the destination ports
+ used to route traffic to an endpoint. Using a port override
+ lets you map a list of external destination ports (that
+ your users send traffic to) to a list of internal destination
+ ports that you want an application endpoint to receive
+ traffic on.
+ items:
+ description: |-
+ PortOverride defines a port override for an endpoint group.
+ Override specific listener ports used to route traffic to endpoints that are part of an endpoint group.
+ For example, you can create a port override in which the listener receives user traffic on ports 80 and 443,
+ but your accelerator routes that traffic to ports 1080 and 1443, respectively, on the endpoints.
+
+
+ For more information, see Port overrides in the AWS Global Accelerator Developer Guide:
+ https://docs.aws.amazon.com/global-accelerator/latest/dg/about-endpoint-groups-port-override.html
+ properties:
+ endpointPort:
+ description: |-
+ EndpointPort is the endpoint port that you want traffic to be routed to.
+ This is the port on the endpoint, such as the Application Load Balancer or Amazon EC2 instance.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ listenerPort:
+ description: |-
+ ListenerPort is the listener port that you want to map to a specific endpoint port.
+ This is the port that user traffic arrives to the Global Accelerator on.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - endpointPort
+ - listenerPort
+ type: object
+ type: array
+ region:
+ description: |-
+ Region is the AWS Region where the endpoint group is located.
+ If unspecified, defaults to the current cluster region.
+ maxLength: 255
+ type: string
+ trafficDialPercentage:
+ default: 100
+ description: |-
+ TrafficDialPercentage is the percentage of traffic to send to an AWS Regions. Additional traffic is distributed to other endpoint groups for this listener
+ Use this action to increase (dial up) or decrease (dial down) traffic to a specific Region. The percentage is applied to the traffic that would otherwise have been routed to the Region based on optimal routing.
+ format: int32
+ maximum: 100
+ minimum: 0
+ type: integer
+ type: object
+ type: array
+ portRanges:
+ description: |-
+ PortRanges is the list of port ranges for the connections from clients to the accelerator.
+ When not specified, the controller will automatically determine the port ranges by inspecting
+ the referenced Kubernetes resources (Service, Ingress, or Gateway) in the endpoint groups.
+ items:
+ description: PortRange defines the port range for Global Accelerator
+ listeners.
+ properties:
+ fromPort:
+ description: FromPort is the first port in the range of
+ ports, inclusive.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ toPort:
+ description: ToPort is the last port in the range of ports,
+ inclusive.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - fromPort
+ - toPort
+ type: object
+ maxItems: 10
+ minItems: 1
+ type: array
+ protocol:
+ description: |-
+ Protocol is the protocol for the connections from clients to the accelerator.
+ When not specified, the controller will automatically determine the protocol by inspecting
+ the referenced Kubernetes resources (Service, Ingress, or Gateway) in the endpoint groups.
+ enum:
+ - TCP
+ - UDP
+ type: string
+ type: object
+ type: array
+ name:
+ description: |-
+ Name is the name of the Global Accelerator.
+ The name must contain only alphanumeric characters or hyphens (-), and must not begin or end with a hyphen.
+ maxLength: 64
+ minLength: 1
+ pattern: ^[a-zA-Z0-9_-]{1,64}$
+ type: string
+ tags:
+ additionalProperties:
+ type: string
+ description: Tags defines list of Tags on the Global Accelerator.
+ type: object
+ type: object
+ status:
+ description: GlobalAcceleratorStatus defines the observed state of GlobalAccelerator
+ properties:
+ acceleratorARN:
+ description: AcceleratorARN is the Amazon Resource Name (ARN) of the
+ accelerator.
+ type: string
+ conditions:
+ description: Conditions represent the current conditions of the GlobalAccelerator.
+ items:
+ description: "Condition contains details for one aspect of the current
+ state of this API Resource.\n---\nThis struct is intended for
+ direct use as an array at the field path .status.conditions. For
+ example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
+ observations of a foo's current state.\n\t // Known .status.conditions.type
+ are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
+ +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
+ \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
+ patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
+ \ // other fields\n\t}"
+ properties:
+ lastTransitionTime:
+ description: |-
+ lastTransitionTime is the last time the condition transitioned from one status to another.
+ This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: |-
+ message is a human readable message indicating details about the transition.
+ This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: |-
+ observedGeneration represents the .metadata.generation that the condition was set based upon.
+ For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
+ with respect to the current state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: |-
+ reason contains a programmatic identifier indicating the reason for the condition's last transition.
+ Producers of specific condition types may define expected values and meanings for this field,
+ and whether the values are considered a guaranteed API.
+ The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: |-
+ type of condition in CamelCase or in foo.example.com/CamelCase.
+ ---
+ Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
+ useful (see .node.status.conditions), the ability to deconflict is important.
+ The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ dnsName:
+ description: DNSName The Domain Name System (DNS) name that Global
+ Accelerator creates that points to an accelerator's static IPv4
+ addresses.
+ type: string
+ dualStackDnsName:
+ description: 'DualStackDnsName is the Domain Name System (DNS) name
+ that Global Accelerator creates that points to a dual-stack accelerator''s
+ four static IP addresses: two IPv4 addresses and two IPv6 addresses.'
+ type: string
+ ipSets:
+ description: IPSets is the static IP addresses that Global Accelerator
+ associates with the accelerator.
+ items:
+ description: IPSet is the static IP addresses that Global Accelerator
+ associates with the accelerator.
+ properties:
+ ipAddressFamily:
+ description: IpAddressFamily is the types of IP addresses included
+ in this IP set.
+ type: string
+ ipAddresses:
+ description: IpAddresses is the array of IP addresses in the
+ IP address set.
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ observedGeneration:
+ description: The generation observed by the GlobalAccelerator controller.
+ format: int64
+ type: integer
+ status:
+ description: Status is the current status of the accelerator.
+ type: string
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
diff --git a/config/crd/aga/aga.k8s.aws_globalaccelerators.yaml b/config/crd/aga/aga.k8s.aws_globalaccelerators.yaml
new file mode 100644
index 000000000..adad811f7
--- /dev/null
+++ b/config/crd/aga/aga.k8s.aws_globalaccelerators.yaml
@@ -0,0 +1,414 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.14.0
+ name: globalaccelerators.aga.k8s.aws
+spec:
+ group: aga.k8s.aws
+ names:
+ kind: GlobalAccelerator
+ listKind: GlobalAcceleratorList
+ plural: globalaccelerators
+ singular: globalaccelerator
+ scope: Namespaced
+ versions:
+ - additionalPrinterColumns:
+ - description: The Global Accelerator name
+ jsonPath: .spec.name
+ name: NAME
+ type: string
+ - description: The Global Accelerator DNS name
+ jsonPath: .status.dnsName
+ name: DNS-NAME
+ type: string
+ - description: The Global Accelerator type
+ jsonPath: .spec.type
+ name: TYPE
+ type: string
+ - description: The Global Accelerator status
+ jsonPath: .status.status
+ name: STATUS
+ type: string
+ - description: The Global Accelerator ARN
+ jsonPath: .status.acceleratorARN
+ name: ARN
+ priority: 1
+ type: string
+ - jsonPath: .metadata.creationTimestamp
+ name: AGE
+ type: date
+ name: v1beta1
+ schema:
+ openAPIV3Schema:
+ description: GlobalAccelerator is the Schema for the GlobalAccelerator API
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: GlobalAcceleratorSpec defines the desired state of GlobalAccelerator
+ properties:
+ ipAddressType:
+ default: IPV4
+ description: IPAddressType is the value for the address type.
+ enum:
+ - IPV4
+ - DUAL_STACK
+ type: string
+ ipAddresses:
+ description: |-
+ IpAddresses optionally specifies the IP addresses from your own IP address pool (BYOIP) to use for the accelerator's static IP addresses.
+ You can specify one or two addresses. Do not include the /32 suffix.
+ If you bring your own IP address pool to Global Accelerator (BYOIP), you can choose an IPv4 address from your own pool to use for the accelerator's static IPv4 address.
+ After you bring an address range to AWS, it appears in your account as an address pool. When you create an accelerator, you can assign one IPv4 address from your range to it.
+ Global Accelerator assigns you a second static IPv4 address from an Amazon IP address range. If you bring two IPv4 address ranges to AWS, you can assign one IPv4 address from each range to your accelerator.
+ Note that you can't update IP addresses for an existing accelerator. To change them, you must create a new accelerator with the new addresses.
+ For more information, see Bring your own IP addresses (BYOIP) in the AWS Global Accelerator Developer Guide.
+ https://docs.aws.amazon.com/global-accelerator/latest/dg/using-byoip.html
+ items:
+ type: string
+ maxItems: 2
+ minItems: 1
+ type: array
+ listeners:
+ description: Listeners defines the listeners for the Global Accelerator.
+ items:
+ description: GlobalAcceleratorListener defines a listener for the
+ Global Accelerator.
+ properties:
+ clientAffinity:
+ default: NONE
+ description: |-
+ ClientAffinity lets you direct all requests from a user to the same endpoint, if you have stateful applications, regardless of the port and protocol of the client request.
+ Client affinity gives you control over whether to always route each client to the same specific endpoint.
+ AWS Global Accelerator uses a consistent-flow hashing algorithm to choose the optimal endpoint for a connection.
+ If client affinity is NONE, Global Accelerator uses the "five-tuple" (5-tuple) properties—source IP address, source port, destination IP address, destination port, and protocol—to select the hash value, and then chooses the best endpoint.
+ However, with this setting, if someone uses different ports to connect to Global Accelerator, their connections might not be always routed to the same endpoint because the hash value changes.
+ If you want a given client to always be routed to the same endpoint, set client affinity to SOURCE_IP instead.
+ When you use the SOURCE_IP setting, Global Accelerator uses the "two-tuple" (2-tuple) properties— source (client) IP address and destination IP address—to select the hash value.
+ The default value is NONE.
+ enum:
+ - SOURCE_IP
+ - NONE
+ type: string
+ endpointGroups:
+ description: EndpointGroups defines a list of endpoint groups
+ for a Global Accelerator listener.
+ items:
+ description: GlobalAcceleratorEndpointGroup defines an endpoint
+ group for a Global Accelerator listener.
+ properties:
+ endpoints:
+ description: Endpoints is the list of endpoint configurations
+ for this endpoint group.
+ items:
+ description: GlobalAcceleratorEndpoint defines an endpoint
+ for a Global Accelerator endpoint group.
+ properties:
+ clientIPPreservationEnabled:
+ default: true
+ description: |-
+ ClientIPPreservationEnabled indicates whether client IP address preservation is enabled for an Application Load Balancer endpoint.
+ The value is true or false. The default value is true for new accelerators.
+ If the value is set to true, the client's IP address is preserved in the X-Forwarded-For request header as traffic travels to applications on the Application Load Balancer endpoint fronted by the accelerator.
+ For more information, see Preserve Client IP Addresses in the AWS Global Accelerator Developer Guide:
+ https://docs.aws.amazon.com/global-accelerator/latest/dg/preserve-client-ip-address.html
+ type: boolean
+ endpointID:
+ description: |-
+ EndpointID is the ID of the endpoint when type is EndpointID.
+ If the endpoint is a Network Load Balancer or Application Load Balancer, this is the Amazon Resource Name (ARN) of the resource.
+ A resource must be valid and active when you add it as an endpoint.
+ Mandatory for remote regions.
+ maxLength: 255
+ type: string
+ name:
+ description: Name is the name of the Kubernetes
+ resource when type is Service, Ingress, or Gateway.
+ type: string
+ namespace:
+ description: |-
+ Namespace is the namespace of the Kubernetes resource when type is Service, Ingress, or Gateway.
+ If not specified, defaults to the same namespace as the GlobalAccelerator resource.
+ type: string
+ type:
+ description: Type specifies the type of endpoint
+ reference.
+ enum:
+ - EndpointID
+ - Service
+ - Ingress
+ - Gateway
+ type: string
+ weight:
+ default: 128
+ description: |-
+ Weight is the weight associated with the endpoint. When you add weights to endpoints, you configure Global Accelerator to route traffic based on proportions that you specify.
+ For example, you might specify endpoint weights of 4, 5, 5, and 6 (sum=20). The result is that 4/20 of your traffic, on average, is routed to the first endpoint,
+ 5/20 is routed both to the second and third endpoints, and 6/20 is routed to the last endpoint.
+ For more information, see Endpoint Weights in the AWS Global Accelerator Developer Guide:
+ https://docs.aws.amazon.com/global-accelerator/latest/dg/about-endpoints-endpoint-weights.html
+ format: int32
+ maximum: 255
+ minimum: 0
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: endpointID is required and name must not
+ be set when type is EndpointID
+ rule: self.type != 'EndpointID' || (has(self.endpointID)
+ && !has(self.name))
+ - message: name is required and endpointID must not
+ be set when type is Service/Ingress/Gateway
+ rule: self.type == 'EndpointID' || (has(self.name)
+ && !has(self.endpointID))
+ type: array
+ portOverrides:
+ description: PortOverrides is a list of endpoint port
+ overrides. Allows you to override the destination ports
+ used to route traffic to an endpoint. Using a port override
+ lets you map a list of external destination ports (that
+ your users send traffic to) to a list of internal destination
+ ports that you want an application endpoint to receive
+ traffic on.
+ items:
+ description: |-
+ PortOverride defines a port override for an endpoint group.
+ Override specific listener ports used to route traffic to endpoints that are part of an endpoint group.
+ For example, you can create a port override in which the listener receives user traffic on ports 80 and 443,
+ but your accelerator routes that traffic to ports 1080 and 1443, respectively, on the endpoints.
+
+
+ For more information, see Port overrides in the AWS Global Accelerator Developer Guide:
+ https://docs.aws.amazon.com/global-accelerator/latest/dg/about-endpoint-groups-port-override.html
+ properties:
+ endpointPort:
+ description: |-
+ EndpointPort is the endpoint port that you want traffic to be routed to.
+ This is the port on the endpoint, such as the Application Load Balancer or Amazon EC2 instance.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ listenerPort:
+ description: |-
+ ListenerPort is the listener port that you want to map to a specific endpoint port.
+ This is the port that user traffic arrives to the Global Accelerator on.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - endpointPort
+ - listenerPort
+ type: object
+ type: array
+ region:
+ description: |-
+ Region is the AWS Region where the endpoint group is located.
+ If unspecified, defaults to the current cluster region.
+ maxLength: 255
+ type: string
+ trafficDialPercentage:
+ default: 100
+ description: |-
+ TrafficDialPercentage is the percentage of traffic to send to an AWS Regions. Additional traffic is distributed to other endpoint groups for this listener
+ Use this action to increase (dial up) or decrease (dial down) traffic to a specific Region. The percentage is applied to the traffic that would otherwise have been routed to the Region based on optimal routing.
+ format: int32
+ maximum: 100
+ minimum: 0
+ type: integer
+ type: object
+ type: array
+ portRanges:
+ description: |-
+ PortRanges is the list of port ranges for the connections from clients to the accelerator.
+ When not specified, the controller will automatically determine the port ranges by inspecting
+ the referenced Kubernetes resources (Service, Ingress, or Gateway) in the endpoint groups.
+ items:
+ description: PortRange defines the port range for Global Accelerator
+ listeners.
+ properties:
+ fromPort:
+ description: FromPort is the first port in the range of
+ ports, inclusive.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ toPort:
+ description: ToPort is the last port in the range of ports,
+ inclusive.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - fromPort
+ - toPort
+ type: object
+ maxItems: 10
+ minItems: 1
+ type: array
+ protocol:
+ description: |-
+ Protocol is the protocol for the connections from clients to the accelerator.
+ When not specified, the controller will automatically determine the protocol by inspecting
+ the referenced Kubernetes resources (Service, Ingress, or Gateway) in the endpoint groups.
+ enum:
+ - TCP
+ - UDP
+ type: string
+ type: object
+ type: array
+ name:
+ description: |-
+ Name is the name of the Global Accelerator.
+ The name must contain only alphanumeric characters or hyphens (-), and must not begin or end with a hyphen.
+ maxLength: 64
+ minLength: 1
+ pattern: ^[a-zA-Z0-9_-]{1,64}$
+ type: string
+ tags:
+ additionalProperties:
+ type: string
+ description: Tags defines list of Tags on the Global Accelerator.
+ type: object
+ type: object
+ status:
+ description: GlobalAcceleratorStatus defines the observed state of GlobalAccelerator
+ properties:
+ acceleratorARN:
+ description: AcceleratorARN is the Amazon Resource Name (ARN) of the
+ accelerator.
+ type: string
+ conditions:
+ description: Conditions represent the current conditions of the GlobalAccelerator.
+ items:
+ description: "Condition contains details for one aspect of the current
+ state of this API Resource.\n---\nThis struct is intended for
+ direct use as an array at the field path .status.conditions. For
+ example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
+ observations of a foo's current state.\n\t // Known .status.conditions.type
+ are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
+ +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
+ \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
+ patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
+ \ // other fields\n\t}"
+ properties:
+ lastTransitionTime:
+ description: |-
+ lastTransitionTime is the last time the condition transitioned from one status to another.
+ This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: |-
+ message is a human readable message indicating details about the transition.
+ This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: |-
+ observedGeneration represents the .metadata.generation that the condition was set based upon.
+ For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
+ with respect to the current state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: |-
+ reason contains a programmatic identifier indicating the reason for the condition's last transition.
+ Producers of specific condition types may define expected values and meanings for this field,
+ and whether the values are considered a guaranteed API.
+ The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: |-
+ type of condition in CamelCase or in foo.example.com/CamelCase.
+ ---
+ Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
+ useful (see .node.status.conditions), the ability to deconflict is important.
+ The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ dnsName:
+ description: DNSName The Domain Name System (DNS) name that Global
+ Accelerator creates that points to an accelerator's static IPv4
+ addresses.
+ type: string
+ dualStackDnsName:
+ description: 'DualStackDnsName is the Domain Name System (DNS) name
+ that Global Accelerator creates that points to a dual-stack accelerator''s
+ four static IP addresses: two IPv4 addresses and two IPv6 addresses.'
+ type: string
+ ipSets:
+ description: IPSets is the static IP addresses that Global Accelerator
+ associates with the accelerator.
+ items:
+ description: IPSet is the static IP addresses that Global Accelerator
+ associates with the accelerator.
+ properties:
+ ipAddressFamily:
+ description: IpAddressFamily is the types of IP addresses included
+ in this IP set.
+ type: string
+ ipAddresses:
+ description: IpAddresses is the array of IP addresses in the
+ IP address set.
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ observedGeneration:
+ description: The generation observed by the GlobalAccelerator controller.
+ format: int64
+ type: integer
+ status:
+ description: Status is the current status of the accelerator.
+ type: string
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
diff --git a/config/crd/aga/kustomization.yaml b/config/crd/aga/kustomization.yaml
new file mode 100644
index 000000000..0b4f4af7d
--- /dev/null
+++ b/config/crd/aga/kustomization.yaml
@@ -0,0 +1,4 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+resources:
+ - aga.k8s.aws_globalaccelerators.yaml
diff --git a/docs/guide/globalaccelerator/spec.md b/docs/guide/globalaccelerator/spec.md
new file mode 100644
index 000000000..f57bbf81c
--- /dev/null
+++ b/docs/guide/globalaccelerator/spec.md
@@ -0,0 +1,267 @@
+# API Reference
+
+## Packages
+- [aga.k8s.aws/v1beta1](#agak8sawsv1beta1)
+
+
+## aga.k8s.aws/v1beta1
+
+Package v1beta1 contains API Schema definitions for the aga v1beta1 API group
+
+### Resource Types
+- [GlobalAccelerator](#globalaccelerator)
+
+
+
+#### ClientAffinityType
+
+_Underlying type:_ _string_
+
+ClientAffinityType defines the client affinity for Global Accelerator listeners.
+
+_Validation:_
+- Enum: [SOURCE_IP NONE]
+
+_Appears in:_
+- [GlobalAcceleratorListener](#globalacceleratorlistener)
+
+| Field | Description |
+| --- | --- |
+| `SOURCE_IP` | |
+| `NONE` | |
+
+
+#### GlobalAccelerator
+
+
+
+GlobalAccelerator is the Schema for the GlobalAccelerator API
+
+
+
+
+
+| Field | Description | Default | Validation |
+| --- | --- | --- | --- |
+| `apiVersion` _string_ | `aga.k8s.aws/v1beta1` | | |
+| `kind` _string_ | `GlobalAccelerator` | | |
+| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. | | |
+| `spec` _[GlobalAcceleratorSpec](#globalacceleratorspec)_ | | | |
+| `status` _[GlobalAcceleratorStatus](#globalacceleratorstatus)_ | | | |
+
+
+#### GlobalAcceleratorEndpoint
+
+
+
+GlobalAcceleratorEndpoint defines an endpoint for a Global Accelerator endpoint group.
+
+
+
+_Appears in:_
+- [GlobalAcceleratorEndpointGroup](#globalacceleratorendpointgroup)
+
+| Field | Description | Default | Validation |
+| --- | --- | --- | --- |
+| `type` _[GlobalAcceleratorEndpointType](#globalacceleratorendpointtype)_ | Type specifies the type of endpoint reference. | | Enum: [EndpointID Service Ingress Gateway]
|
+| `endpointID` _string_ | EndpointID is the ID of the endpoint when type is EndpointID.
If the endpoint is a Network Load Balancer or Application Load Balancer, this is the Amazon Resource Name (ARN) of the resource.
A resource must be valid and active when you add it as an endpoint.
Mandatory for remote regions. | | MaxLength: 255
|
+| `name` _string_ | Name is the name of the Kubernetes resource when type is Service, Ingress, or Gateway. | | |
+| `namespace` _string_ | Namespace is the namespace of the Kubernetes resource when type is Service, Ingress, or Gateway.
If not specified, defaults to the same namespace as the GlobalAccelerator resource. | | |
+| `weight` _integer_ | Weight is the weight associated with the endpoint. When you add weights to endpoints, you configure Global Accelerator to route traffic based on proportions that you specify.
For example, you might specify endpoint weights of 4, 5, 5, and 6 (sum=20). The result is that 4/20 of your traffic, on average, is routed to the first endpoint,
5/20 is routed both to the second and third endpoints, and 6/20 is routed to the last endpoint.
For more information, see Endpoint Weights in the AWS Global Accelerator Developer Guide:
https://docs.aws.amazon.com/global-accelerator/latest/dg/about-endpoints-endpoint-weights.html | 128 | Maximum: 255
Minimum: 0
|
+| `clientIPPreservationEnabled` _boolean_ | ClientIPPreservationEnabled indicates whether client IP address preservation is enabled for an Application Load Balancer endpoint.
The value is true or false. The default value is true for new accelerators.
If the value is set to true, the client's IP address is preserved in the X-Forwarded-For request header as traffic travels to applications on the Application Load Balancer endpoint fronted by the accelerator.
For more information, see Preserve Client IP Addresses in the AWS Global Accelerator Developer Guide:
https://docs.aws.amazon.com/global-accelerator/latest/dg/preserve-client-ip-address.html | true | |
+
+
+#### GlobalAcceleratorEndpointGroup
+
+
+
+GlobalAcceleratorEndpointGroup defines an endpoint group for a Global Accelerator listener.
+
+
+
+_Appears in:_
+- [GlobalAcceleratorListener](#globalacceleratorlistener)
+
+| Field | Description | Default | Validation |
+| --- | --- | --- | --- |
+| `region` _string_ | Region is the AWS Region where the endpoint group is located.
If unspecified, defaults to the current cluster region. | | MaxLength: 255
|
+| `trafficDialPercentage` _integer_ | TrafficDialPercentage is the percentage of traffic to send to an AWS Regions. Additional traffic is distributed to other endpoint groups for this listener
Use this action to increase (dial up) or decrease (dial down) traffic to a specific Region. The percentage is applied to the traffic that would otherwise have been routed to the Region based on optimal routing. | 100 | Maximum: 100
Minimum: 0
|
+| `portOverrides` _[PortOverride](#portoverride)_ | PortOverrides is a list of endpoint port overrides. Allows you to override the destination ports used to route traffic to an endpoint. Using a port override lets you map a list of external destination ports (that your users send traffic to) to a list of internal destination ports that you want an application endpoint to receive traffic on. | | |
+| `endpoints` _[GlobalAcceleratorEndpoint](#globalacceleratorendpoint)_ | Endpoints is the list of endpoint configurations for this endpoint group. | | |
+
+
+#### GlobalAcceleratorEndpointType
+
+_Underlying type:_ _string_
+
+GlobalAcceleratorEndpointType defines the type of endpoint for Global Accelerator.
+
+_Validation:_
+- Enum: [EndpointID Service Ingress Gateway]
+
+_Appears in:_
+- [GlobalAcceleratorEndpoint](#globalacceleratorendpoint)
+
+| Field | Description |
+| --- | --- |
+| `EndpointID` | |
+| `Service` | |
+| `Ingress` | |
+| `Gateway` | |
+
+
+#### GlobalAcceleratorListener
+
+
+
+GlobalAcceleratorListener defines a listener for the Global Accelerator.
+
+
+
+_Appears in:_
+- [GlobalAcceleratorSpec](#globalacceleratorspec)
+
+| Field | Description | Default | Validation |
+| --- | --- | --- | --- |
+| `protocol` _[GlobalAcceleratorProtocol](#globalacceleratorprotocol)_ | Protocol is the protocol for the connections from clients to the accelerator.
When not specified, the controller will automatically determine the protocol by inspecting
the referenced Kubernetes resources (Service, Ingress, or Gateway) in the endpoint groups. | | Enum: [TCP UDP]
|
+| `portRanges` _[PortRange](#portrange)_ | PortRanges is the list of port ranges for the connections from clients to the accelerator.
When not specified, the controller will automatically determine the port ranges by inspecting
the referenced Kubernetes resources (Service, Ingress, or Gateway) in the endpoint groups. | | MaxItems: 10
MinItems: 1
|
+| `clientAffinity` _[ClientAffinityType](#clientaffinitytype)_ | ClientAffinity lets you direct all requests from a user to the same endpoint, if you have stateful applications, regardless of the port and protocol of the client request.
Client affinity gives you control over whether to always route each client to the same specific endpoint.
AWS Global Accelerator uses a consistent-flow hashing algorithm to choose the optimal endpoint for a connection.
If client affinity is NONE, Global Accelerator uses the "five-tuple" (5-tuple) properties—source IP address, source port, destination IP address, destination port, and protocol—to select the hash value, and then chooses the best endpoint.
However, with this setting, if someone uses different ports to connect to Global Accelerator, their connections might not be always routed to the same endpoint because the hash value changes.
If you want a given client to always be routed to the same endpoint, set client affinity to SOURCE_IP instead.
When you use the SOURCE_IP setting, Global Accelerator uses the "two-tuple" (2-tuple) properties— source (client) IP address and destination IP address—to select the hash value.
The default value is NONE. | NONE | Enum: [SOURCE_IP NONE]
|
+| `endpointGroups` _[GlobalAcceleratorEndpointGroup](#globalacceleratorendpointgroup)_ | EndpointGroups defines a list of endpoint groups for a Global Accelerator listener. | | |
+
+
+#### GlobalAcceleratorProtocol
+
+_Underlying type:_ _string_
+
+GlobalAcceleratorProtocol defines the protocol for Global Accelerator listeners.
+
+_Validation:_
+- Enum: [TCP UDP]
+
+_Appears in:_
+- [GlobalAcceleratorListener](#globalacceleratorlistener)
+
+| Field | Description |
+| --- | --- |
+| `TCP` | |
+| `UDP` | |
+
+
+#### GlobalAcceleratorSpec
+
+
+
+GlobalAcceleratorSpec defines the desired state of GlobalAccelerator
+
+
+
+_Appears in:_
+- [GlobalAccelerator](#globalaccelerator)
+
+| Field | Description | Default | Validation |
+| --- | --- | --- | --- |
+| `name` _string_ | Name is the name of the Global Accelerator.
The name must contain only alphanumeric characters or hyphens (-), and must not begin or end with a hyphen. | | MaxLength: 64
MinLength: 1
Pattern: `^[a-zA-Z0-9_-]\{1,64\}$`
|
+| `ipAddresses` _string_ | IpAddresses optionally specifies the IP addresses from your own IP address pool (BYOIP) to use for the accelerator's static IP addresses.
You can specify one or two addresses. Do not include the /32 suffix.
If you bring your own IP address pool to Global Accelerator (BYOIP), you can choose an IPv4 address from your own pool to use for the accelerator's static IPv4 address.
After you bring an address range to AWS, it appears in your account as an address pool. When you create an accelerator, you can assign one IPv4 address from your range to it.
Global Accelerator assigns you a second static IPv4 address from an Amazon IP address range. If you bring two IPv4 address ranges to AWS, you can assign one IPv4 address from each range to your accelerator.
Note that you can't update IP addresses for an existing accelerator. To change them, you must create a new accelerator with the new addresses.
For more information, see Bring your own IP addresses (BYOIP) in the AWS Global Accelerator Developer Guide.
https://docs.aws.amazon.com/global-accelerator/latest/dg/using-byoip.html | | MaxItems: 2
MinItems: 1
|
+| `ipAddressType` _[IPAddressType](#ipaddresstype)_ | IPAddressType is the value for the address type. | IPV4 | Enum: [IPV4 DUAL_STACK]
|
+| `tags` _map[string]string_ | Tags defines list of Tags on the Global Accelerator. | | |
+| `listeners` _[GlobalAcceleratorListener](#globalacceleratorlistener)_ | Listeners defines the listeners for the Global Accelerator. | | |
+
+
+#### GlobalAcceleratorStatus
+
+
+
+GlobalAcceleratorStatus defines the observed state of GlobalAccelerator
+
+
+
+_Appears in:_
+- [GlobalAccelerator](#globalaccelerator)
+
+| Field | Description | Default | Validation |
+| --- | --- | --- | --- |
+| `observedGeneration` _integer_ | The generation observed by the GlobalAccelerator controller. | | |
+| `acceleratorARN` _string_ | AcceleratorARN is the Amazon Resource Name (ARN) of the accelerator. | | |
+| `dnsName` _string_ | DNSName The Domain Name System (DNS) name that Global Accelerator creates that points to an accelerator's static IPv4 addresses. | | |
+| `dualStackDnsName` _string_ | DualStackDnsName is the Domain Name System (DNS) name that Global Accelerator creates that points to a dual-stack accelerator's four static IP addresses: two IPv4 addresses and two IPv6 addresses. | | |
+| `ipSets` _[IPSet](#ipset) array_ | IPSets is the static IP addresses that Global Accelerator associates with the accelerator. | | |
+| `status` _string_ | Status is the current status of the accelerator. | | |
+| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#condition-v1-meta) array_ | Conditions represent the current conditions of the GlobalAccelerator. | | |
+
+
+#### IPAddressType
+
+_Underlying type:_ _string_
+
+IPAddressType defines the IP address type for Global Accelerator.
+
+_Validation:_
+- Enum: [IPV4 DUAL_STACK]
+
+_Appears in:_
+- [GlobalAcceleratorSpec](#globalacceleratorspec)
+
+| Field | Description |
+| --- | --- |
+| `IPV4` | |
+| `DUAL_STACK` | |
+
+
+#### IPSet
+
+
+
+IPSet is the static IP addresses that Global Accelerator associates with the accelerator.
+
+
+
+_Appears in:_
+- [GlobalAcceleratorStatus](#globalacceleratorstatus)
+
+| Field | Description | Default | Validation |
+| --- | --- | --- | --- |
+| `ipAddresses` _string_ | IpAddresses is the array of IP addresses in the IP address set. | | |
+| `ipAddressFamily` _string_ | IpAddressFamily is the types of IP addresses included in this IP set. | | |
+
+
+#### PortOverride
+
+
+
+PortOverride defines a port override for an endpoint group.
+Override specific listener ports used to route traffic to endpoints that are part of an endpoint group.
+For example, you can create a port override in which the listener receives user traffic on ports 80 and 443,
+but your accelerator routes that traffic to ports 1080 and 1443, respectively, on the endpoints.
+
+
+For more information, see Port overrides in the AWS Global Accelerator Developer Guide:
+https://docs.aws.amazon.com/global-accelerator/latest/dg/about-endpoint-groups-port-override.html
+
+
+
+_Appears in:_
+- [GlobalAcceleratorEndpointGroup](#globalacceleratorendpointgroup)
+
+| Field | Description | Default | Validation |
+| --- | --- | --- | --- |
+| `listenerPort` _integer_ | ListenerPort is the listener port that you want to map to a specific endpoint port.
This is the port that user traffic arrives to the Global Accelerator on. | | Maximum: 65535
Minimum: 1
|
+| `endpointPort` _integer_ | EndpointPort is the endpoint port that you want traffic to be routed to.
This is the port on the endpoint, such as the Application Load Balancer or Amazon EC2 instance. | | Maximum: 65535
Minimum: 1
|
+
+
+#### PortRange
+
+
+
+PortRange defines the port range for Global Accelerator listeners.
+
+
+
+_Appears in:_
+- [GlobalAcceleratorListener](#globalacceleratorlistener)
+
+| Field | Description | Default | Validation |
+| --- | --- | --- | --- |
+| `fromPort` _integer_ | FromPort is the first port in the range of ports, inclusive. | | Maximum: 65535
Minimum: 1
|
+| `toPort` _integer_ | ToPort is the last port in the range of ports, inclusive. | | Maximum: 65535
Minimum: 1
|
+
+
diff --git a/helm/aws-load-balancer-controller/crds/aga-crds.yaml b/helm/aws-load-balancer-controller/crds/aga-crds.yaml
new file mode 100644
index 000000000..adad811f7
--- /dev/null
+++ b/helm/aws-load-balancer-controller/crds/aga-crds.yaml
@@ -0,0 +1,414 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.14.0
+ name: globalaccelerators.aga.k8s.aws
+spec:
+ group: aga.k8s.aws
+ names:
+ kind: GlobalAccelerator
+ listKind: GlobalAcceleratorList
+ plural: globalaccelerators
+ singular: globalaccelerator
+ scope: Namespaced
+ versions:
+ - additionalPrinterColumns:
+ - description: The Global Accelerator name
+ jsonPath: .spec.name
+ name: NAME
+ type: string
+ - description: The Global Accelerator DNS name
+ jsonPath: .status.dnsName
+ name: DNS-NAME
+ type: string
+ - description: The Global Accelerator type
+ jsonPath: .spec.type
+ name: TYPE
+ type: string
+ - description: The Global Accelerator status
+ jsonPath: .status.status
+ name: STATUS
+ type: string
+ - description: The Global Accelerator ARN
+ jsonPath: .status.acceleratorARN
+ name: ARN
+ priority: 1
+ type: string
+ - jsonPath: .metadata.creationTimestamp
+ name: AGE
+ type: date
+ name: v1beta1
+ schema:
+ openAPIV3Schema:
+ description: GlobalAccelerator is the Schema for the GlobalAccelerator API
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: GlobalAcceleratorSpec defines the desired state of GlobalAccelerator
+ properties:
+ ipAddressType:
+ default: IPV4
+ description: IPAddressType is the value for the address type.
+ enum:
+ - IPV4
+ - DUAL_STACK
+ type: string
+ ipAddresses:
+ description: |-
+ IpAddresses optionally specifies the IP addresses from your own IP address pool (BYOIP) to use for the accelerator's static IP addresses.
+ You can specify one or two addresses. Do not include the /32 suffix.
+ If you bring your own IP address pool to Global Accelerator (BYOIP), you can choose an IPv4 address from your own pool to use for the accelerator's static IPv4 address.
+ After you bring an address range to AWS, it appears in your account as an address pool. When you create an accelerator, you can assign one IPv4 address from your range to it.
+ Global Accelerator assigns you a second static IPv4 address from an Amazon IP address range. If you bring two IPv4 address ranges to AWS, you can assign one IPv4 address from each range to your accelerator.
+ Note that you can't update IP addresses for an existing accelerator. To change them, you must create a new accelerator with the new addresses.
+ For more information, see Bring your own IP addresses (BYOIP) in the AWS Global Accelerator Developer Guide.
+ https://docs.aws.amazon.com/global-accelerator/latest/dg/using-byoip.html
+ items:
+ type: string
+ maxItems: 2
+ minItems: 1
+ type: array
+ listeners:
+ description: Listeners defines the listeners for the Global Accelerator.
+ items:
+ description: GlobalAcceleratorListener defines a listener for the
+ Global Accelerator.
+ properties:
+ clientAffinity:
+ default: NONE
+ description: |-
+ ClientAffinity lets you direct all requests from a user to the same endpoint, if you have stateful applications, regardless of the port and protocol of the client request.
+ Client affinity gives you control over whether to always route each client to the same specific endpoint.
+ AWS Global Accelerator uses a consistent-flow hashing algorithm to choose the optimal endpoint for a connection.
+ If client affinity is NONE, Global Accelerator uses the "five-tuple" (5-tuple) properties—source IP address, source port, destination IP address, destination port, and protocol—to select the hash value, and then chooses the best endpoint.
+ However, with this setting, if someone uses different ports to connect to Global Accelerator, their connections might not be always routed to the same endpoint because the hash value changes.
+ If you want a given client to always be routed to the same endpoint, set client affinity to SOURCE_IP instead.
+ When you use the SOURCE_IP setting, Global Accelerator uses the "two-tuple" (2-tuple) properties— source (client) IP address and destination IP address—to select the hash value.
+ The default value is NONE.
+ enum:
+ - SOURCE_IP
+ - NONE
+ type: string
+ endpointGroups:
+ description: EndpointGroups defines a list of endpoint groups
+ for a Global Accelerator listener.
+ items:
+ description: GlobalAcceleratorEndpointGroup defines an endpoint
+ group for a Global Accelerator listener.
+ properties:
+ endpoints:
+ description: Endpoints is the list of endpoint configurations
+ for this endpoint group.
+ items:
+ description: GlobalAcceleratorEndpoint defines an endpoint
+ for a Global Accelerator endpoint group.
+ properties:
+ clientIPPreservationEnabled:
+ default: true
+ description: |-
+ ClientIPPreservationEnabled indicates whether client IP address preservation is enabled for an Application Load Balancer endpoint.
+ The value is true or false. The default value is true for new accelerators.
+ If the value is set to true, the client's IP address is preserved in the X-Forwarded-For request header as traffic travels to applications on the Application Load Balancer endpoint fronted by the accelerator.
+ For more information, see Preserve Client IP Addresses in the AWS Global Accelerator Developer Guide:
+ https://docs.aws.amazon.com/global-accelerator/latest/dg/preserve-client-ip-address.html
+ type: boolean
+ endpointID:
+ description: |-
+ EndpointID is the ID of the endpoint when type is EndpointID.
+ If the endpoint is a Network Load Balancer or Application Load Balancer, this is the Amazon Resource Name (ARN) of the resource.
+ A resource must be valid and active when you add it as an endpoint.
+ Mandatory for remote regions.
+ maxLength: 255
+ type: string
+ name:
+ description: Name is the name of the Kubernetes
+ resource when type is Service, Ingress, or Gateway.
+ type: string
+ namespace:
+ description: |-
+ Namespace is the namespace of the Kubernetes resource when type is Service, Ingress, or Gateway.
+ If not specified, defaults to the same namespace as the GlobalAccelerator resource.
+ type: string
+ type:
+ description: Type specifies the type of endpoint
+ reference.
+ enum:
+ - EndpointID
+ - Service
+ - Ingress
+ - Gateway
+ type: string
+ weight:
+ default: 128
+ description: |-
+ Weight is the weight associated with the endpoint. When you add weights to endpoints, you configure Global Accelerator to route traffic based on proportions that you specify.
+ For example, you might specify endpoint weights of 4, 5, 5, and 6 (sum=20). The result is that 4/20 of your traffic, on average, is routed to the first endpoint,
+ 5/20 is routed both to the second and third endpoints, and 6/20 is routed to the last endpoint.
+ For more information, see Endpoint Weights in the AWS Global Accelerator Developer Guide:
+ https://docs.aws.amazon.com/global-accelerator/latest/dg/about-endpoints-endpoint-weights.html
+ format: int32
+ maximum: 255
+ minimum: 0
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: endpointID is required and name must not
+ be set when type is EndpointID
+ rule: self.type != 'EndpointID' || (has(self.endpointID)
+ && !has(self.name))
+ - message: name is required and endpointID must not
+ be set when type is Service/Ingress/Gateway
+ rule: self.type == 'EndpointID' || (has(self.name)
+ && !has(self.endpointID))
+ type: array
+ portOverrides:
+ description: PortOverrides is a list of endpoint port
+ overrides. Allows you to override the destination ports
+ used to route traffic to an endpoint. Using a port override
+ lets you map a list of external destination ports (that
+ your users send traffic to) to a list of internal destination
+ ports that you want an application endpoint to receive
+ traffic on.
+ items:
+ description: |-
+ PortOverride defines a port override for an endpoint group.
+ Override specific listener ports used to route traffic to endpoints that are part of an endpoint group.
+ For example, you can create a port override in which the listener receives user traffic on ports 80 and 443,
+ but your accelerator routes that traffic to ports 1080 and 1443, respectively, on the endpoints.
+
+
+ For more information, see Port overrides in the AWS Global Accelerator Developer Guide:
+ https://docs.aws.amazon.com/global-accelerator/latest/dg/about-endpoint-groups-port-override.html
+ properties:
+ endpointPort:
+ description: |-
+ EndpointPort is the endpoint port that you want traffic to be routed to.
+ This is the port on the endpoint, such as the Application Load Balancer or Amazon EC2 instance.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ listenerPort:
+ description: |-
+ ListenerPort is the listener port that you want to map to a specific endpoint port.
+ This is the port that user traffic arrives to the Global Accelerator on.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - endpointPort
+ - listenerPort
+ type: object
+ type: array
+ region:
+ description: |-
+ Region is the AWS Region where the endpoint group is located.
+ If unspecified, defaults to the current cluster region.
+ maxLength: 255
+ type: string
+ trafficDialPercentage:
+ default: 100
+ description: |-
+ TrafficDialPercentage is the percentage of traffic to send to an AWS Regions. Additional traffic is distributed to other endpoint groups for this listener
+ Use this action to increase (dial up) or decrease (dial down) traffic to a specific Region. The percentage is applied to the traffic that would otherwise have been routed to the Region based on optimal routing.
+ format: int32
+ maximum: 100
+ minimum: 0
+ type: integer
+ type: object
+ type: array
+ portRanges:
+ description: |-
+ PortRanges is the list of port ranges for the connections from clients to the accelerator.
+ When not specified, the controller will automatically determine the port ranges by inspecting
+ the referenced Kubernetes resources (Service, Ingress, or Gateway) in the endpoint groups.
+ items:
+ description: PortRange defines the port range for Global Accelerator
+ listeners.
+ properties:
+ fromPort:
+ description: FromPort is the first port in the range of
+ ports, inclusive.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ toPort:
+ description: ToPort is the last port in the range of ports,
+ inclusive.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - fromPort
+ - toPort
+ type: object
+ maxItems: 10
+ minItems: 1
+ type: array
+ protocol:
+ description: |-
+ Protocol is the protocol for the connections from clients to the accelerator.
+ When not specified, the controller will automatically determine the protocol by inspecting
+ the referenced Kubernetes resources (Service, Ingress, or Gateway) in the endpoint groups.
+ enum:
+ - TCP
+ - UDP
+ type: string
+ type: object
+ type: array
+ name:
+ description: |-
+ Name is the name of the Global Accelerator.
+ The name must contain only alphanumeric characters or hyphens (-), and must not begin or end with a hyphen.
+ maxLength: 64
+ minLength: 1
+ pattern: ^[a-zA-Z0-9_-]{1,64}$
+ type: string
+ tags:
+ additionalProperties:
+ type: string
+ description: Tags defines list of Tags on the Global Accelerator.
+ type: object
+ type: object
+ status:
+ description: GlobalAcceleratorStatus defines the observed state of GlobalAccelerator
+ properties:
+ acceleratorARN:
+ description: AcceleratorARN is the Amazon Resource Name (ARN) of the
+ accelerator.
+ type: string
+ conditions:
+ description: Conditions represent the current conditions of the GlobalAccelerator.
+ items:
+ description: "Condition contains details for one aspect of the current
+ state of this API Resource.\n---\nThis struct is intended for
+ direct use as an array at the field path .status.conditions. For
+ example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
+ observations of a foo's current state.\n\t // Known .status.conditions.type
+ are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
+ +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
+ \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
+ patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
+ \ // other fields\n\t}"
+ properties:
+ lastTransitionTime:
+ description: |-
+ lastTransitionTime is the last time the condition transitioned from one status to another.
+ This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: |-
+ message is a human readable message indicating details about the transition.
+ This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: |-
+ observedGeneration represents the .metadata.generation that the condition was set based upon.
+ For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
+ with respect to the current state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: |-
+ reason contains a programmatic identifier indicating the reason for the condition's last transition.
+ Producers of specific condition types may define expected values and meanings for this field,
+ and whether the values are considered a guaranteed API.
+ The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: |-
+ type of condition in CamelCase or in foo.example.com/CamelCase.
+ ---
+ Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
+ useful (see .node.status.conditions), the ability to deconflict is important.
+ The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ dnsName:
+ description: DNSName The Domain Name System (DNS) name that Global
+ Accelerator creates that points to an accelerator's static IPv4
+ addresses.
+ type: string
+ dualStackDnsName:
+ description: 'DualStackDnsName is the Domain Name System (DNS) name
+ that Global Accelerator creates that points to a dual-stack accelerator''s
+ four static IP addresses: two IPv4 addresses and two IPv6 addresses.'
+ type: string
+ ipSets:
+ description: IPSets is the static IP addresses that Global Accelerator
+ associates with the accelerator.
+ items:
+ description: IPSet is the static IP addresses that Global Accelerator
+ associates with the accelerator.
+ properties:
+ ipAddressFamily:
+ description: IpAddressFamily is the types of IP addresses included
+ in this IP set.
+ type: string
+ ipAddresses:
+ description: IpAddresses is the array of IP addresses in the
+ IP address set.
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ observedGeneration:
+ description: The generation observed by the GlobalAccelerator controller.
+ format: int64
+ type: integer
+ status:
+ description: Status is the current status of the accelerator.
+ type: string
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
diff --git a/mkdocs.yml b/mkdocs.yml
index b7523d075..b20d9261a 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -39,6 +39,8 @@ nav:
- TargetGroupConfiguration: guide/gateway/targetgroupconfig.md
- ListenerRuleConfiguration: guide/gateway/listenerruleconfig.md
- Specification: guide/gateway/spec.md
+ - Global Accelerator:
+ - Specification: guide/globalaccelerator/spec.md
- Tasks:
- Cognito Authentication: guide/tasks/cognito_authentication.md
- SSL Redirect: guide/tasks/ssl_redirect.md