diff --git a/api/v1alpha1/gateway_types.go b/api/v1alpha1/gateway_types.go index aee7551229..4d960a9d47 100644 --- a/api/v1alpha1/gateway_types.go +++ b/api/v1alpha1/gateway_types.go @@ -23,7 +23,10 @@ import ( // +kubebuilder:object:root=true // +kubebuilder:subresource:status -// Gateway represents an instantiation of a service-traffic handling infrastructure. +// Gateway represents an instantiation of a service-traffic handling +// infrastructure. The distinguishing characteristics of a gateway are +// that it has at least one IP address, and that it behaves as a network +// endpoint from the perspective of a client application. type Gateway struct { metav1.TypeMeta `json:",inline" protobuf:"bytes,1,opt,name=typeMeta"` metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,2,opt,name=metadata"` @@ -54,78 +57,185 @@ type GatewayList struct { type GatewaySpec struct { // Class used for this Gateway. This is the name of a GatewayClass resource. Class string `json:"class" protobuf:"bytes,1,opt,name=class"` - // Listeners associated with this Gateway. Listeners define what addresses, - // ports, protocols are bound on this Gateway. + + // Listeners associated with this Gateway. Listeners define logical + // endpoints that are bound on this Gateway. If no Listeners are + // provided, the GatewayClass may associate the Gateway with + // an address but the Gateway will not be able to accept any + // connections. + // + // +optional Listeners []Listener `json:"listeners" protobuf:"bytes,2,rep,name=listeners"` - // Routes specifies a schema for associating routes with the Gateway using - // selectors. A route is a resource capable of servicing a request and allows - // a cluster operator to expose a cluster resource (i.e. Service) by - // externally-reachable URL, load-balance traffic and terminate SSL/TLS. - // Typically, a route is a "httproute" or "tcproute" in group - // "networking.x-k8s.io". However, an implementation may support other resources. + + // Address requested for this gateway. This is optional and behavior + // can depend on the GatewayClass. If a value is set in the spec and + // the requested address is invalid, the GatewayClass MUST indicate + // this in the associated entry in GatewayStatus.Listeners. If no + // addresses are specified, the GatewayClass may schedule the Gateway + // in an implementation-defined manner, providing it with an appropriate + // set of addresses. // - // Support: Core + // Support: // - Routes RouteBindingSelector `json:"routes" protobuf:"bytes,3,opt,name=routes"` + // +optional + Addresses []ListenerAddress `json:"endpoints" protobuf:"bytes,3,rep,name=endpoints"` } +// ProtocolType defines the application protocol accepted by a Listener. +type ProtocolType string + const ( - // HTTPProtocol constant. - HTTPProtocol = "HTTP" - // HTTPSProtocol constant. - HTTPSProtocol = "HTTPS" + // HTTPProtocolType accepts cleartext HTTP/1.1 sessions over TCP. + HTTPProtocolType ProtocolType = "HTTP" + + // HTTPSProtocolType accepts HTTP/1.1 or HTTP/2 sessions over TLS. + HTTPSProtocolType ProtocolType = "HTTPS" + + // TLSProtocolType accepts TLS sessions over TCP. + TLSProtocolType ProtocolType = "TLS" + + // TCPProtocolType accepts TCP sessions. + TCPProtocolType ProtocolType = "TCP" ) -// Listener defines a +// HostnameMatchType specifies the types of matches that are valid +// for host names. +type HostnameMatchType string + +const ( + // HostnameMatchDomain specifies that the host name provided by the + // client should be matched against a DNS domain value. The domain + // match should follow the wildcard certificate matching rules in + // [RFC 6125](https://tools.ietf.org/html/rfc6125#section-6.4.3). + HostnameMatchDomain HostnameMatchType = "Domain" + + // HostnameMatchExact specifies that the host name provided by the + // client must exactly match the specified value. + HostnameMatchExact HostnameMatchType = "Exact" +) + +// HostnameMatch specifies how a Listener should match the host name from a +// client request. Depending on the incoming protocol, the match may apply to +// the TLS and the HTTP protocol. +type HostnameMatch struct { + // Match specifies how the host name provided by the client should be + // matched against the given value. + // + // +optional + // +kubebuilder:validation:Enum=Domain;Exact + // +kubebuilder:default=Exact + Match HostnameMatchType `json:"match" protobuf:"bytes,1,name=match"` + + // Value contains the value to match against. This value must be a + // fully qualified host or domain name as defined by + // [RFC 3986](https://tools.ietf.org/html/rfc3986#section-3.2.2). + // Note the following deviations from the "host" part of the URI as defined in the RFC: + // + // 1. IPs are not allowed. + // 2. The `:` delimiter is not respected because ports are not allowed. + // + // +required + // +kubebuilder:validation:MinLength=1 + Value string `json:"value" protobuf:"bytes,2,name=value"` +} + +// Listener embodies the concept of a logical endpoint where a +// Gateway can accept network connections. +// +// The GatewayClass may collapse Listener definitions into single +// implementation-defined acceptor configuration. This allows Gateways to +// be implemented in terms of virtual services configured within the same +// proxy server process. +// +// Listeners may be considered collapsible if the Protocol field is +// "HTTP", "HTTPS" or "TLS", the Hostname field is specified, and the Port +// field matches. As a special case, each group of collapsed Listeners may +// contain up to one Listener that omits the Hostname field. Listeners that +// specify identical Hostname fields must not be treated as collapsible. +// +// If the GatewayClass collapses Listeners, the Hostname field must be matched +// in order of most to least specific. "Exact" matches must be processed before +// "Domain" matches, which must be processed before Listeners with no Hostname +// field. +// +// If the Gateway specifies multiple Listeners that have the same Port value +// but are not collapsible, the GatewayClass must raise a "PortConflict" +// condition on the Gateway. type Listener struct { - // Name is the listener's name and should be specified as an - // RFC 1035 DNS_LABEL [1]: + // Hostname specifies the virtual host name for protocol types + // that define this concept. // - // [1] https://tools.ietf.org/html/rfc1035 + // Incoming requests are matched against Hostname before processing + // HTTPRoute rules. For example, if the HTTP request header + // contains "Host: foo.example.com", an Listener with Hostname value + // "foo.example.com" will be an "Exact" match, but a Listener with + // Hostname values "example.com" or "bar.example.com" will not + // match. However these host names would match against a "Domain" + // match type with a value of "example.com". // - // Each listener of a Gateway must have a unique name. Name is used - // for associating a listener in Gateway status. + // If Hostname is unspecified, the Gateway routes all traffic based on + // the specified rules. // - // Support: Core + // A Hostname match should be supplied for "HTTP" and "HTTPS" + // protocols, and may be supplied for "TLS" protocol. If no + // match is supplied, then this Listener must accept all client + // connections on the specified Port. // - // +required - Name string `json:"name" protobuf:"bytes,1,opt,name=name"` - // Address requested for this listener. This is optional and behavior - // can depend on GatewayClass. If a value is set in the spec and - // the request address is invalid, the GatewayClass MUST indicate - // this in the associated entry in GatewayStatus.Listeners. + // As Listener that omits this field may be collapsed with other + // Listeners on the same port and protocol. There may be only + // one such Listener per Port. If more that one is configured, + // the GatewayClass must raise a "NameConflict" condition. // - // Support: + // Support: Core // // +optional - Address *ListenerAddress `json:"address,omitempty" protobuf:"bytes,2,opt,name=address"` - // Port is a list of ports associated with the Address. + Hostname *HostnameMatch `json:"hostname,omitempty" protobuf:"bytes,1,opt,name=hostname"` + + // Port is the network port. Multiple listeners may use the + // same port, subject to the Listener collapsing rules. // - // Support: - // +optional - Port *int32 `json:"port,omitempty" protobuf:"varint,3,opt,name=port"` - // Protocol to use. + // Support: Core // - // Support: - // +optional - Protocol *string `json:"protocol,omitempty" protobuf:"bytes,4,opt,name=protocol"` + // +required + Port int32 `json:"port,omitempty" protobuf:"varint,2,opt,name=port"` + + // Protocol specifies the application protocol this listener expects to receive. + // + // Support: Core + // + // +required + // +kubebuilder:validation:Enum=HTTP;HTTPS;TLS;TCP + Protocol ProtocolType `json:"protocol,omitempty" protobuf:"bytes,3,opt,name=protocol"` + // TLS is the TLS configuration for the Listener. If unspecified, - // the listener will not support TLS connections. + // the Listener will not support TLS connections. If the Hostname + // field is also specified, this endpoint must only accept TLS + // sessions where the client sends a TLS Server Name Indication (SNI) + // extension, and that value matches against the Listener's Hostname + // field. + // + // If the Protocol field is "HTTPS" or "TLS", this field is required. // // Support: Core // // +optional - TLS *TLSConfig `json:"tls,omitempty" protobuf:"bytes,5,opt,name=tls"` - // ExtensionRef for this Listener. The resource may be "configmaps" or - // an implementation-defined resource (for example, resource - // "mylisteners" in group "networking.acme.io"). Omitting or specifying - // the empty string for both the resource and group indicates that the - // resource is "configmaps". If the referent cannot be found, the - // listener's "InvalidListener" status condition will be true. - // - // Support: custom. - // +optional - ExtensionRef *ListenerExtensionObjectReference `json:"extensionRef,omitempty" protobuf:"bytes,6,opt,name=extensionRef"` + TLS *TLSConfig `json:"tls,omitempty" protobuf:"bytes,4,opt,name=tls"` + + // Routes specifies a schema for associating routes with the Gateway using + // selectors. A route is a resource capable of servicing a request and allows + // a cluster operator to expose a cluster resource (i.e. Service) by + // externally-reachable URL, load-balance traffic and terminate SSL/TLS. + // Typically, a route is a "httproute" or "tcproute" in group + // "networking.x-k8s.io". However, an implementation may support other resources. + // + // The Routes selector must select a set of objects that + // are compatible with the application protocol specified in + // the Protocol field. + // + // Support: Core + // + // +required + Routes RouteBindingSelector `json:"routes" protobuf:"bytes,5,opt,name=routes"` } // AddressType defines how a network address is represented as a text string. @@ -259,8 +369,12 @@ type GatewayCondition struct { // ListenerStatus is the status associated with each listener block. type ListenerStatus struct { // Name is the name of the listener this status refers to. + // TODO(jpeach) Listeners are not indexexd by a unique name any more, + // so this field probably doesn't make sense. Name string `json:"name" protobuf:"bytes,1,opt,name=name"` // Address bound on this listener. + // TODO(jpeach) Listeners don't have addresses anymore so this field + // should move to the GatewayStatus. Address *ListenerAddress `json:"address" protobuf:"bytes,2,opt,name=address"` // Conditions describe the current condition of this listener. Conditions []ListenerCondition `json:"conditions" protobuf:"bytes,3,rep,name=conditions"` @@ -285,6 +399,10 @@ const ( // ConditionNameConflict indicates that two or more Listeners with // the same name were bound to this gateway. ConditionNameConflict ListenerConditionType = "NameConflict" + // ConditionPortConflict indicates that two or more Listeners with + // the same port were bound to this gateway and they could not be + // collapsed into a single configuration. + ConditionPortConflict ListenerConditionType = "PortConflict" // ConditionInvalidCertificateRef indicates the certificate reference of the // listener's TLS configuration is invalid. ConditionInvalidCertificateRef ListenerConditionType = "InvalidCertificateRef" diff --git a/api/v1alpha1/generated.pb.go b/api/v1alpha1/generated.pb.go index 1a83c6ad16..024c83c79f 100644 --- a/api/v1alpha1/generated.pb.go +++ b/api/v1alpha1/generated.pb.go @@ -690,10 +690,38 @@ func (m *HTTPRouteStatus) XXX_DiscardUnknown() { var xxx_messageInfo_HTTPRouteStatus proto.InternalMessageInfo +func (m *HostnameMatch) Reset() { *m = HostnameMatch{} } +func (*HostnameMatch) ProtoMessage() {} +func (*HostnameMatch) Descriptor() ([]byte, []int) { + return fileDescriptor_40fafbfb106ed5b2, []int{23} +} +func (m *HostnameMatch) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HostnameMatch) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *HostnameMatch) XXX_Merge(src proto.Message) { + xxx_messageInfo_HostnameMatch.Merge(m, src) +} +func (m *HostnameMatch) XXX_Size() int { + return m.Size() +} +func (m *HostnameMatch) XXX_DiscardUnknown() { + xxx_messageInfo_HostnameMatch.DiscardUnknown(m) +} + +var xxx_messageInfo_HostnameMatch proto.InternalMessageInfo + func (m *Listener) Reset() { *m = Listener{} } func (*Listener) ProtoMessage() {} func (*Listener) Descriptor() ([]byte, []int) { - return fileDescriptor_40fafbfb106ed5b2, []int{23} + return fileDescriptor_40fafbfb106ed5b2, []int{24} } func (m *Listener) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -721,7 +749,7 @@ var xxx_messageInfo_Listener proto.InternalMessageInfo func (m *ListenerAddress) Reset() { *m = ListenerAddress{} } func (*ListenerAddress) ProtoMessage() {} func (*ListenerAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_40fafbfb106ed5b2, []int{24} + return fileDescriptor_40fafbfb106ed5b2, []int{25} } func (m *ListenerAddress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -749,7 +777,7 @@ var xxx_messageInfo_ListenerAddress proto.InternalMessageInfo func (m *ListenerCondition) Reset() { *m = ListenerCondition{} } func (*ListenerCondition) ProtoMessage() {} func (*ListenerCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_40fafbfb106ed5b2, []int{25} + return fileDescriptor_40fafbfb106ed5b2, []int{26} } func (m *ListenerCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -777,7 +805,7 @@ var xxx_messageInfo_ListenerCondition proto.InternalMessageInfo func (m *ListenerStatus) Reset() { *m = ListenerStatus{} } func (*ListenerStatus) ProtoMessage() {} func (*ListenerStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_40fafbfb106ed5b2, []int{26} + return fileDescriptor_40fafbfb106ed5b2, []int{27} } func (m *ListenerStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -805,7 +833,7 @@ var xxx_messageInfo_ListenerStatus proto.InternalMessageInfo func (m *RouteBindingSelector) Reset() { *m = RouteBindingSelector{} } func (*RouteBindingSelector) ProtoMessage() {} func (*RouteBindingSelector) Descriptor() ([]byte, []int) { - return fileDescriptor_40fafbfb106ed5b2, []int{27} + return fileDescriptor_40fafbfb106ed5b2, []int{28} } func (m *RouteBindingSelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -833,7 +861,7 @@ var xxx_messageInfo_RouteBindingSelector proto.InternalMessageInfo func (m *SecretsDefaultLocalObjectReference) Reset() { *m = SecretsDefaultLocalObjectReference{} } func (*SecretsDefaultLocalObjectReference) ProtoMessage() {} func (*SecretsDefaultLocalObjectReference) Descriptor() ([]byte, []int) { - return fileDescriptor_40fafbfb106ed5b2, []int{28} + return fileDescriptor_40fafbfb106ed5b2, []int{29} } func (m *SecretsDefaultLocalObjectReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -861,7 +889,7 @@ var xxx_messageInfo_SecretsDefaultLocalObjectReference proto.InternalMessageInfo func (m *ServicesDefaultLocalObjectReference) Reset() { *m = ServicesDefaultLocalObjectReference{} } func (*ServicesDefaultLocalObjectReference) ProtoMessage() {} func (*ServicesDefaultLocalObjectReference) Descriptor() ([]byte, []int) { - return fileDescriptor_40fafbfb106ed5b2, []int{29} + return fileDescriptor_40fafbfb106ed5b2, []int{30} } func (m *ServicesDefaultLocalObjectReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -889,7 +917,7 @@ var xxx_messageInfo_ServicesDefaultLocalObjectReference proto.InternalMessageInf func (m *TLSConfig) Reset() { *m = TLSConfig{} } func (*TLSConfig) ProtoMessage() {} func (*TLSConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_40fafbfb106ed5b2, []int{30} + return fileDescriptor_40fafbfb106ed5b2, []int{31} } func (m *TLSConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -917,7 +945,7 @@ var xxx_messageInfo_TLSConfig proto.InternalMessageInfo func (m *TcpRoute) Reset() { *m = TcpRoute{} } func (*TcpRoute) ProtoMessage() {} func (*TcpRoute) Descriptor() ([]byte, []int) { - return fileDescriptor_40fafbfb106ed5b2, []int{31} + return fileDescriptor_40fafbfb106ed5b2, []int{32} } func (m *TcpRoute) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -945,7 +973,7 @@ var xxx_messageInfo_TcpRoute proto.InternalMessageInfo func (m *TcpRouteList) Reset() { *m = TcpRouteList{} } func (*TcpRouteList) ProtoMessage() {} func (*TcpRouteList) Descriptor() ([]byte, []int) { - return fileDescriptor_40fafbfb106ed5b2, []int{32} + return fileDescriptor_40fafbfb106ed5b2, []int{33} } func (m *TcpRouteList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -973,7 +1001,7 @@ var xxx_messageInfo_TcpRouteList proto.InternalMessageInfo func (m *TcpRouteSpec) Reset() { *m = TcpRouteSpec{} } func (*TcpRouteSpec) ProtoMessage() {} func (*TcpRouteSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_40fafbfb106ed5b2, []int{33} + return fileDescriptor_40fafbfb106ed5b2, []int{34} } func (m *TcpRouteSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1001,7 +1029,7 @@ var xxx_messageInfo_TcpRouteSpec proto.InternalMessageInfo func (m *TcpRouteStatus) Reset() { *m = TcpRouteStatus{} } func (*TcpRouteStatus) ProtoMessage() {} func (*TcpRouteStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_40fafbfb106ed5b2, []int{34} + return fileDescriptor_40fafbfb106ed5b2, []int{35} } func (m *TcpRouteStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1029,7 +1057,7 @@ var xxx_messageInfo_TcpRouteStatus proto.InternalMessageInfo func (m *TrafficSplit) Reset() { *m = TrafficSplit{} } func (*TrafficSplit) ProtoMessage() {} func (*TrafficSplit) Descriptor() ([]byte, []int) { - return fileDescriptor_40fafbfb106ed5b2, []int{35} + return fileDescriptor_40fafbfb106ed5b2, []int{36} } func (m *TrafficSplit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1057,7 +1085,7 @@ var xxx_messageInfo_TrafficSplit proto.InternalMessageInfo func (m *TrafficSplitList) Reset() { *m = TrafficSplitList{} } func (*TrafficSplitList) ProtoMessage() {} func (*TrafficSplitList) Descriptor() ([]byte, []int) { - return fileDescriptor_40fafbfb106ed5b2, []int{36} + return fileDescriptor_40fafbfb106ed5b2, []int{37} } func (m *TrafficSplitList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1085,7 +1113,7 @@ var xxx_messageInfo_TrafficSplitList proto.InternalMessageInfo func (m *TrafficSplitSpec) Reset() { *m = TrafficSplitSpec{} } func (*TrafficSplitSpec) ProtoMessage() {} func (*TrafficSplitSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_40fafbfb106ed5b2, []int{37} + return fileDescriptor_40fafbfb106ed5b2, []int{38} } func (m *TrafficSplitSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1113,7 +1141,7 @@ var xxx_messageInfo_TrafficSplitSpec proto.InternalMessageInfo func (m *TrafficSplitStatus) Reset() { *m = TrafficSplitStatus{} } func (*TrafficSplitStatus) ProtoMessage() {} func (*TrafficSplitStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_40fafbfb106ed5b2, []int{38} + return fileDescriptor_40fafbfb106ed5b2, []int{39} } func (m *TrafficSplitStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1164,6 +1192,7 @@ func init() { proto.RegisterType((*HTTPRouteRule)(nil), "k8s.io.service_apis.api.v1alpha1.HTTPRouteRule") proto.RegisterType((*HTTPRouteSpec)(nil), "k8s.io.service_apis.api.v1alpha1.HTTPRouteSpec") proto.RegisterType((*HTTPRouteStatus)(nil), "k8s.io.service_apis.api.v1alpha1.HTTPRouteStatus") + proto.RegisterType((*HostnameMatch)(nil), "k8s.io.service_apis.api.v1alpha1.HostnameMatch") proto.RegisterType((*Listener)(nil), "k8s.io.service_apis.api.v1alpha1.Listener") proto.RegisterType((*ListenerAddress)(nil), "k8s.io.service_apis.api.v1alpha1.ListenerAddress") proto.RegisterType((*ListenerCondition)(nil), "k8s.io.service_apis.api.v1alpha1.ListenerCondition") @@ -1188,144 +1217,148 @@ func init() { } var fileDescriptor_40fafbfb106ed5b2 = []byte{ - // 2185 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0xcd, 0x8f, 0x1c, 0x47, - 0x15, 0xdf, 0x9e, 0x8f, 0xdd, 0x99, 0xb7, 0xdf, 0x85, 0x63, 0x36, 0x4b, 0xb4, 0x6b, 0xb5, 0x09, - 0x8a, 0x4d, 0xdc, 0x63, 0x6f, 0x8c, 0x59, 0x9b, 0x70, 0xd8, 0xd9, 0xd8, 0x5e, 0xa4, 0x5d, 0x7b, - 0x53, 0x33, 0x98, 0x24, 0x58, 0x81, 0x72, 0x4f, 0xcd, 0x6c, 0xb3, 0x3d, 0xdd, 0xad, 0xee, 0x9a, - 0x35, 0x2b, 0x81, 0x14, 0x7c, 0xc9, 0x35, 0x20, 0x71, 0x08, 0x1f, 0xa7, 0x5c, 0xf9, 0x17, 0x38, - 0x63, 0x71, 0xca, 0x31, 0xe2, 0x30, 0xc2, 0x83, 0x50, 0x0e, 0x1c, 0x82, 0x40, 0x20, 0xe1, 0x13, - 0xaa, 0x8f, 0xfe, 0x9a, 0xd9, 0xd9, 0xe9, 0x09, 0xfe, 0x60, 0x11, 0xb7, 0xae, 0x57, 0xaf, 0x7e, - 0xaf, 0xde, 0xab, 0x57, 0xbf, 0x7a, 0x55, 0x33, 0xf0, 0xb5, 0xc0, 0x6a, 0x05, 0xc6, 0xfe, 0x7a, - 0x60, 0x58, 0x6e, 0x25, 0xa0, 0xfe, 0x81, 0x65, 0xd2, 0x0b, 0xc4, 0xb3, 0x82, 0x0a, 0xf1, 0xac, - 0xca, 0xc1, 0x25, 0x62, 0x7b, 0x7b, 0xe4, 0x52, 0xa5, 0x45, 0x1d, 0xea, 0x13, 0x46, 0x1b, 0x86, - 0xe7, 0xbb, 0xcc, 0x45, 0x67, 0xe4, 0x08, 0x43, 0x8d, 0xf8, 0x1e, 0x1f, 0x61, 0x10, 0xcf, 0x32, - 0xc2, 0x11, 0xcb, 0x17, 0x5a, 0x16, 0xdb, 0xeb, 0xdc, 0x33, 0x4c, 0xb7, 0x5d, 0x69, 0xb9, 0x2d, - 0xb7, 0x22, 0x06, 0xde, 0xeb, 0x34, 0x45, 0x4b, 0x34, 0xc4, 0x97, 0x04, 0x5c, 0xd6, 0xd5, 0x14, - 0xb8, 0x55, 0xd3, 0xf5, 0x69, 0xe5, 0x60, 0xc0, 0xe8, 0xf2, 0xe5, 0x58, 0xa7, 0x4d, 0xcc, 0x3d, - 0xcb, 0xa1, 0xfe, 0x61, 0xc5, 0xdb, 0x6f, 0x55, 0xc4, 0x7c, 0xdb, 0x94, 0x91, 0xa3, 0x46, 0x5d, - 0x19, 0x36, 0xca, 0xef, 0x38, 0xcc, 0x6a, 0xd3, 0x4a, 0x60, 0xee, 0xd1, 0x36, 0x19, 0x18, 0x77, - 0x35, 0x19, 0x19, 0xd3, 0x75, 0x98, 0xef, 0xda, 0x36, 0xf5, 0x2f, 0x84, 0xc3, 0x38, 0x84, 0x18, - 0x4a, 0xfb, 0x87, 0xea, 0xbf, 0xd2, 0xe0, 0xe5, 0x4d, 0xd7, 0x69, 0x5a, 0xad, 0x1d, 0xe2, 0x05, - 0x6f, 0xd0, 0x26, 0xe9, 0xd8, 0x6c, 0xdb, 0x35, 0x89, 0x7d, 0xfb, 0xde, 0x0f, 0xa8, 0xc9, 0x30, - 0x6d, 0x52, 0x9f, 0x3a, 0x26, 0x45, 0x67, 0xa1, 0xd8, 0xf2, 0xdd, 0x8e, 0xb7, 0xa4, 0x9d, 0xd1, - 0x5e, 0x29, 0x57, 0x67, 0x1f, 0x76, 0x57, 0x27, 0x7a, 0xdd, 0xd5, 0xe2, 0x4d, 0x2e, 0xc4, 0xb2, - 0x0f, 0xbd, 0x0a, 0x25, 0x9f, 0x06, 0x6e, 0xc7, 0x37, 0xe9, 0x52, 0x4e, 0xe8, 0x2d, 0x28, 0xbd, - 0x12, 0x56, 0x72, 0x1c, 0x69, 0xa0, 0x33, 0x50, 0x70, 0x48, 0x9b, 0x2e, 0xe5, 0x85, 0xe6, 0x8c, - 0xd2, 0x2c, 0xdc, 0x22, 0x6d, 0x8a, 0x45, 0x8f, 0xfe, 0x3b, 0x0d, 0xe6, 0x6f, 0xb8, 0xfe, 0x7d, - 0xe2, 0x37, 0xea, 0x6e, 0x9d, 0xf8, 0x2d, 0xca, 0xd0, 0x01, 0x94, 0x99, 0xf8, 0xc2, 0xb4, 0x29, - 0x26, 0x33, 0xbd, 0x76, 0xdd, 0x18, 0xb5, 0xc8, 0x46, 0x4d, 0xf6, 0x1c, 0xe7, 0x62, 0x75, 0x51, - 0xcd, 0xa0, 0x5c, 0x0f, 0xf1, 0x71, 0x6c, 0x0a, 0xbd, 0x0e, 0x20, 0x1b, 0xbb, 0xae, 0xcf, 0x84, - 0x77, 0xc5, 0xea, 0x4b, 0xbd, 0xee, 0x2a, 0xd4, 0x23, 0xe9, 0xe3, 0x54, 0x0b, 0x27, 0xf4, 0xf5, - 0xbf, 0xe7, 0x60, 0xea, 0x26, 0x61, 0xf4, 0x3e, 0x39, 0x44, 0x77, 0xa1, 0xc4, 0x0e, 0x3d, 0xba, - 0x43, 0x19, 0x51, 0x0e, 0x18, 0xa1, 0x03, 0xc9, 0xa5, 0x37, 0xbc, 0xfd, 0x96, 0x21, 0x3c, 0xe1, - 0x09, 0x63, 0x1c, 0x5c, 0x32, 0xea, 0x6a, 0x54, 0x1c, 0xd5, 0x50, 0x82, 0x23, 0x44, 0xf4, 0x7d, - 0x28, 0x71, 0xfd, 0x06, 0x61, 0x44, 0xcc, 0x72, 0x7a, 0xed, 0x62, 0x36, 0x74, 0x19, 0x0e, 0x81, - 0x8f, 0x14, 0x3e, 0xc4, 0x32, 0x1c, 0xa1, 0xa2, 0xdb, 0x50, 0x08, 0x3c, 0x6a, 0x8a, 0x75, 0x9b, - 0x5e, 0xbb, 0x30, 0x3a, 0xf8, 0xca, 0xf1, 0x9a, 0x47, 0xcd, 0x78, 0x99, 0x79, 0x0b, 0x0b, 0x20, - 0xf4, 0x1d, 0x98, 0x0c, 0x18, 0x61, 0x9d, 0x60, 0xa9, 0x20, 0x20, 0x2b, 0xd9, 0x21, 0xc5, 0xb0, - 0xea, 0x9c, 0x02, 0x9d, 0x94, 0x6d, 0xac, 0xe0, 0xf4, 0x07, 0x79, 0x98, 0x51, 0x9a, 0x9b, 0x36, - 0x09, 0x82, 0x54, 0xe8, 0x0b, 0x4f, 0x35, 0xf4, 0xda, 0x53, 0x09, 0x7d, 0x5d, 0x85, 0x5e, 0x2e, - 0xec, 0x5a, 0xe6, 0x38, 0x09, 0xef, 0x87, 0xc6, 0xff, 0x6e, 0x14, 0x7f, 0xb9, 0xa4, 0x97, 0xc7, - 0xc4, 0x3d, 0x7e, 0x11, 0x3e, 0xcb, 0xc1, 0x0b, 0x49, 0xf5, 0x4d, 0xd7, 0x69, 0x58, 0xcc, 0x72, - 0x1d, 0xf4, 0x4d, 0x28, 0xf0, 0xd8, 0x29, 0x4a, 0x39, 0x17, 0xce, 0x8c, 0x47, 0xf6, 0x71, 0x77, - 0xf5, 0xc5, 0x23, 0x07, 0xf1, 0x4e, 0x2c, 0x86, 0xa1, 0xed, 0x68, 0xda, 0x92, 0x6b, 0x2e, 0xa7, - 0x27, 0xf0, 0xb8, 0xbb, 0x7a, 0x04, 0x57, 0x1b, 0x11, 0x52, 0x7a, 0x9a, 0xe8, 0x2b, 0x30, 0xe9, - 0x53, 0x12, 0xb8, 0x8e, 0xe2, 0xa3, 0xc8, 0x1d, 0x2c, 0xa4, 0x58, 0xf5, 0xa2, 0x73, 0x30, 0xd5, - 0xa6, 0x41, 0x40, 0x5a, 0x54, 0x64, 0x50, 0xb9, 0x3a, 0xaf, 0x14, 0xa7, 0x76, 0xa4, 0x18, 0x87, - 0xfd, 0xe8, 0x00, 0x90, 0x4d, 0x02, 0x56, 0xf7, 0x89, 0x13, 0xc8, 0xc9, 0x5b, 0x6d, 0xba, 0x54, - 0x14, 0x31, 0x3e, 0x9f, 0x31, 0xef, 0xac, 0x36, 0xad, 0x2e, 0x2b, 0x0b, 0x68, 0x7b, 0x00, 0x0d, - 0x1f, 0x61, 0x41, 0xff, 0x28, 0x07, 0x0b, 0xc9, 0xe0, 0x6d, 0x5b, 0x01, 0x4b, 0xa5, 0x7e, 0xfe, - 0x89, 0xa7, 0xfe, 0xdd, 0x81, 0xd4, 0xcf, 0x88, 0xce, 0xe7, 0x96, 0x46, 0x0f, 0x25, 0x89, 0xb4, - 0xaf, 0x41, 0xd1, 0x62, 0xb4, 0xcd, 0x17, 0x3a, 0x9f, 0x84, 0xce, 0x96, 0x9f, 0xf1, 0x61, 0xf5, - 0x2d, 0x0e, 0x82, 0x25, 0x96, 0xfe, 0x69, 0x3e, 0x1d, 0x25, 0xbe, 0x21, 0xd0, 0x1a, 0x40, 0x7c, - 0x82, 0xaa, 0xc4, 0x8c, 0xb6, 0xe4, 0x66, 0xd4, 0x83, 0x13, 0x5a, 0xe8, 0xa7, 0x1a, 0x2c, 0x11, - 0xdb, 0x76, 0xef, 0xd3, 0x86, 0xc2, 0xe3, 0x47, 0x58, 0xe0, 0x11, 0x93, 0x06, 0x6a, 0xa7, 0xbe, - 0x96, 0x31, 0x18, 0xe4, 0x1e, 0xb5, 0x6b, 0xd4, 0xa6, 0x26, 0x73, 0xfd, 0xea, 0x19, 0x65, 0x77, - 0x69, 0x63, 0x08, 0x38, 0x1e, 0x6a, 0x16, 0xbd, 0xaf, 0xc1, 0x69, 0xd5, 0x89, 0xdd, 0x0e, 0xa3, - 0x89, 0x19, 0xe5, 0x3f, 0xff, 0x8c, 0x96, 0x7b, 0xdd, 0xd5, 0xd3, 0x1b, 0x47, 0xc2, 0xe2, 0x21, - 0xe6, 0xd0, 0x7b, 0x1a, 0xcc, 0x7a, 0xc4, 0x27, 0x6d, 0xca, 0xa8, 0x1f, 0xf0, 0x43, 0x5b, 0x12, - 0xef, 0xcd, 0xd1, 0x8b, 0x98, 0xa9, 0x32, 0xa9, 0x2e, 0xf6, 0xba, 0xab, 0xb3, 0xbb, 0x49, 0x0b, - 0x38, 0x6d, 0x50, 0xff, 0x89, 0x06, 0x68, 0x90, 0xb0, 0xd0, 0xbe, 0x58, 0x6b, 0x49, 0x06, 0xc1, - 0x92, 0x26, 0x52, 0xeb, 0xeb, 0xe3, 0xa5, 0x56, 0x44, 0x26, 0xa9, 0x24, 0x51, 0x90, 0x38, 0x01, - 0xaf, 0xff, 0x39, 0xb1, 0x27, 0x23, 0x02, 0x5c, 0x4f, 0x11, 0xe0, 0x97, 0xfb, 0x08, 0xf0, 0x54, - 0xbf, 0xfe, 0x53, 0xe3, 0xbe, 0x04, 0xa7, 0xe5, 0x47, 0x70, 0x5a, 0x4c, 0x93, 0x85, 0x63, 0x69, - 0xf2, 0x79, 0x71, 0xdf, 0x87, 0x39, 0x98, 0x56, 0x71, 0x1b, 0xa0, 0x3d, 0xed, 0xa9, 0xd2, 0x5e, - 0xee, 0x89, 0xd3, 0xde, 0xad, 0x90, 0xf6, 0xf2, 0x22, 0x37, 0xcf, 0x65, 0xce, 0xcd, 0x21, 0x8c, - 0xb7, 0x0f, 0xa7, 0x95, 0x42, 0x7f, 0x75, 0x5f, 0x81, 0xb2, 0x13, 0x6e, 0x59, 0x95, 0x8d, 0x51, - 0x35, 0x1c, 0xed, 0x65, 0x1c, 0xeb, 0x44, 0xb5, 0x7b, 0x6e, 0x68, 0xed, 0xfe, 0x99, 0x16, 0x2d, - 0x84, 0x60, 0xd6, 0xb3, 0x50, 0x34, 0xf9, 0x96, 0xe9, 0xbf, 0x40, 0x88, 0x7d, 0x84, 0x65, 0x1f, - 0xfa, 0x2e, 0x94, 0x6d, 0x2b, 0x60, 0xfc, 0x96, 0x12, 0x92, 0xfd, 0xf9, 0xd1, 0x5e, 0x6f, 0xab, - 0x21, 0xf1, 0x9c, 0x43, 0x49, 0x80, 0x63, 0x3c, 0xf4, 0x2e, 0x4c, 0xfa, 0x9c, 0x9c, 0x42, 0x0a, - 0xbc, 0x32, 0x1a, 0x59, 0x90, 0x59, 0xd5, 0x72, 0x1a, 0x96, 0xd3, 0x8a, 0x58, 0x30, 0x4e, 0x79, - 0x81, 0x86, 0x15, 0xaa, 0xfe, 0x07, 0x0d, 0x66, 0x53, 0x75, 0x29, 0x6a, 0x1e, 0xc1, 0x30, 0x63, - 0x14, 0x6d, 0x59, 0xc9, 0x05, 0x91, 0xc1, 0xb0, 0x5d, 0xcc, 0x1e, 0x36, 0x55, 0xbf, 0x1d, 0x1b, - 0x3c, 0xfd, 0xf7, 0x1a, 0x2c, 0x6c, 0xd5, 0xeb, 0xbb, 0x5b, 0x94, 0x34, 0xa8, 0x7f, 0xc3, 0xb2, - 0x19, 0xf5, 0xd1, 0x3b, 0x90, 0x27, 0x8d, 0x86, 0x72, 0xec, 0x1b, 0xa3, 0x2d, 0xf6, 0x03, 0x18, - 0x1b, 0x8d, 0xc6, 0x75, 0x87, 0xf9, 0x87, 0xd5, 0x69, 0x65, 0x3c, 0xbf, 0xd1, 0x68, 0x60, 0x0e, - 0x8a, 0x74, 0x4e, 0x34, 0x6d, 0xf7, 0x80, 0x0a, 0x87, 0xca, 0x55, 0x90, 0x24, 0xc3, 0x25, 0x58, - 0xf5, 0x2c, 0x5f, 0x81, 0x52, 0x88, 0x80, 0x16, 0x20, 0xbf, 0x4f, 0x0f, 0x65, 0x76, 0x61, 0xfe, - 0x89, 0x4e, 0x41, 0xf1, 0x80, 0xd8, 0x1d, 0x95, 0xa4, 0x58, 0x36, 0xae, 0xe5, 0xd6, 0x35, 0xfd, - 0x5f, 0x39, 0x28, 0xf3, 0xb9, 0x88, 0x05, 0x3c, 0xf1, 0xf7, 0xb1, 0x37, 0x53, 0xf7, 0xb1, 0x4a, - 0xb6, 0x65, 0x10, 0xae, 0x0f, 0xbd, 0x11, 0xbc, 0xdd, 0x77, 0x23, 0xbb, 0x34, 0x0e, 0xe8, 0xf1, - 0xd7, 0x81, 0xbf, 0x6a, 0x30, 0x1f, 0xe9, 0x6e, 0x98, 0xe2, 0x1c, 0x7c, 0x17, 0xca, 0xcd, 0xf0, - 0x9a, 0xaf, 0x96, 0x20, 0x83, 0xc5, 0xbe, 0x97, 0x81, 0xea, 0x2c, 0x4f, 0xde, 0x48, 0x88, 0x63, - 0x48, 0xf4, 0x63, 0x98, 0xa1, 0x3f, 0x64, 0xd4, 0x09, 0x2c, 0xd7, 0xe1, 0x15, 0x48, 0xee, 0xc9, - 0x56, 0x20, 0x0b, 0xbd, 0xee, 0xea, 0xcc, 0xf5, 0x84, 0x01, 0x9c, 0x32, 0xa7, 0xff, 0x25, 0xe9, - 0xb2, 0xda, 0x3a, 0x6f, 0xc3, 0xd4, 0x9e, 0xd8, 0x09, 0x81, 0x72, 0x78, 0x6d, 0xfc, 0xed, 0x53, - 0x9d, 0xe6, 0x47, 0xb4, 0x94, 0x04, 0x38, 0xc4, 0x7b, 0xde, 0xde, 0xfe, 0x2c, 0x07, 0xb3, 0x91, - 0xb7, 0x5b, 0x6e, 0xc0, 0xd0, 0xab, 0x50, 0xda, 0x73, 0x03, 0x26, 0x0e, 0x0c, 0x2d, 0xfd, 0x2c, - 0xb4, 0xa5, 0xe4, 0x38, 0xd2, 0x40, 0x75, 0x28, 0xfa, 0x1d, 0x9b, 0x86, 0x44, 0x36, 0x4e, 0x3e, - 0xe3, 0x8e, 0x4d, 0xe3, 0x93, 0x85, 0xb7, 0x02, 0x2c, 0xc1, 0x06, 0x82, 0x92, 0x7f, 0xb6, 0x41, - 0xf9, 0x75, 0x32, 0x28, 0x27, 0xbe, 0x30, 0xd9, 0x4d, 0x17, 0x26, 0x5f, 0x1d, 0x63, 0x89, 0x86, - 0x94, 0x26, 0xbf, 0xc9, 0xc3, 0x5c, 0xa4, 0xb3, 0x43, 0x98, 0xb9, 0xc7, 0xb3, 0xc6, 0x23, 0x6c, - 0xaf, 0x1e, 0x17, 0xc8, 0xd1, 0x94, 0x76, 0x95, 0x1c, 0x47, 0x1a, 0xe8, 0x25, 0x28, 0xf0, 0x6f, - 0x55, 0x90, 0x94, 0x38, 0x9f, 0x71, 0x2d, 0x2c, 0xa4, 0xc8, 0x00, 0x90, 0xbb, 0x43, 0xa0, 0xa9, - 0x0b, 0x3e, 0x27, 0xd4, 0xad, 0x48, 0x8a, 0x13, 0x1a, 0xa8, 0x01, 0x93, 0xb2, 0xb5, 0x54, 0x10, - 0x1e, 0xbe, 0x3e, 0x86, 0x87, 0x62, 0xf6, 0x86, 0x04, 0x96, 0x87, 0x5b, 0x44, 0x85, 0x52, 0x88, - 0x15, 0xf6, 0x40, 0x4e, 0x16, 0x9f, 0x69, 0x4e, 0x2e, 0x5f, 0x85, 0xe9, 0xc4, 0x2c, 0xc7, 0x3a, - 0x40, 0x3f, 0x48, 0xa6, 0x33, 0xdf, 0x67, 0xe8, 0x4d, 0x28, 0xb6, 0xb9, 0xe3, 0xfd, 0x0f, 0x5f, - 0x59, 0x03, 0x56, 0x2d, 0xf3, 0x9c, 0x10, 0x9f, 0x58, 0x22, 0xa1, 0x6f, 0xc3, 0x64, 0x53, 0xf0, - 0x9c, 0xca, 0xe0, 0x71, 0x0e, 0x21, 0x45, 0x90, 0xa2, 0x68, 0x90, 0xdf, 0x58, 0x81, 0x71, 0x58, - 0x22, 0x8e, 0x1d, 0xc5, 0x01, 0xe3, 0xc0, 0xca, 0xf3, 0x4a, 0xc2, 0xca, 0x6f, 0xac, 0xc0, 0xf4, - 0xdf, 0x6a, 0x89, 0x90, 0x88, 0x8a, 0xb7, 0x0e, 0x45, 0x4e, 0x6a, 0x61, 0xe1, 0x37, 0x0e, 0x91, - 0x71, 0x5a, 0x8c, 0x77, 0x0a, 0x6f, 0x05, 0x58, 0x82, 0xa1, 0x3b, 0x30, 0xd5, 0x90, 0x8b, 0xae, - 0xc2, 0x32, 0x36, 0xae, 0x38, 0x35, 0x54, 0xe2, 0xe0, 0x10, 0x4c, 0x7f, 0x90, 0x3c, 0xa4, 0x54, - 0xfd, 0xea, 0xc2, 0x74, 0x4b, 0xd6, 0xa2, 0x98, 0x36, 0x43, 0x3f, 0xd6, 0x33, 0x17, 0xb0, 0xfd, - 0x09, 0xf9, 0x05, 0xe5, 0x50, 0x78, 0x2f, 0xe0, 0xa0, 0x38, 0x69, 0x41, 0xff, 0x79, 0x1e, 0x4a, - 0x61, 0xf9, 0x19, 0xdd, 0x31, 0xb4, 0x61, 0x77, 0x0c, 0xf4, 0x16, 0x4c, 0x91, 0x46, 0xc3, 0xa7, - 0x41, 0x90, 0x3d, 0x45, 0x42, 0xf8, 0x0d, 0x39, 0x50, 0x46, 0x43, 0x35, 0x70, 0x08, 0x27, 0xe8, - 0xc4, 0xf5, 0x99, 0x48, 0x91, 0xa2, 0xa2, 0x13, 0xd7, 0x67, 0x58, 0x48, 0xd1, 0x2b, 0x50, 0x12, - 0xbf, 0x9f, 0x98, 0xae, 0xad, 0xae, 0xc1, 0x33, 0x82, 0x96, 0x94, 0x0c, 0x47, 0xbd, 0xe8, 0x06, - 0xe4, 0x99, 0x1d, 0xa8, 0x9d, 0x9d, 0x81, 0x27, 0xeb, 0xdb, 0x35, 0xb9, 0xb9, 0xab, 0x53, 0xbc, - 0x1a, 0xae, 0x6f, 0xd7, 0x30, 0x07, 0x18, 0xa0, 0x8a, 0xc9, 0x67, 0x7b, 0x7c, 0xb5, 0x60, 0xbe, - 0x2f, 0x6e, 0xa8, 0x92, 0x7a, 0xbb, 0xf8, 0x52, 0xdf, 0xdb, 0xc5, 0xb4, 0x52, 0x4b, 0x3c, 0x59, - 0x9c, 0x4d, 0xb1, 0x49, 0x9c, 0xdd, 0x77, 0xb8, 0x50, 0x91, 0x8b, 0xfe, 0x69, 0x0e, 0x16, 0x43, - 0x4b, 0xf1, 0x3b, 0xc9, 0xd5, 0x94, 0xad, 0x97, 0xfb, 0x6c, 0xbd, 0x30, 0x30, 0xe0, 0xff, 0x0f, - 0x25, 0xa3, 0x1f, 0x4a, 0xfe, 0xa1, 0xc1, 0x5c, 0xfa, 0x06, 0xf8, 0x5c, 0x37, 0x5c, 0x2b, 0x75, - 0x55, 0x96, 0x75, 0xc5, 0x6b, 0xd9, 0xc1, 0xb3, 0x3f, 0xc4, 0x3d, 0xc8, 0xc1, 0xa9, 0xa3, 0xae, - 0xf5, 0xe8, 0x47, 0xb0, 0x18, 0xbd, 0x6f, 0x84, 0x42, 0x75, 0x9a, 0x7d, 0xae, 0xc7, 0xd2, 0x17, - 0xd5, 0x44, 0x16, 0x6f, 0xf5, 0xa3, 0xe2, 0x41, 0x43, 0xc8, 0x86, 0x59, 0xf1, 0x8c, 0x10, 0x59, - 0xfe, 0x0f, 0x1e, 0x8e, 0xc5, 0x8b, 0x28, 0x4e, 0xa2, 0xe1, 0x34, 0xb8, 0xfe, 0xa1, 0x06, 0x7a, - 0x8d, 0x9a, 0x3e, 0x65, 0xff, 0x7d, 0x3f, 0xfa, 0xfe, 0x42, 0x83, 0xb3, 0x19, 0x7e, 0xae, 0x7d, - 0x3e, 0x93, 0xfb, 0x5b, 0x0e, 0xca, 0x11, 0x47, 0xa3, 0xf7, 0x35, 0x98, 0x37, 0xa9, 0xcf, 0xac, - 0xa6, 0x65, 0x12, 0x46, 0x13, 0x87, 0xe4, 0x1b, 0x59, 0x7e, 0x92, 0x1e, 0x15, 0xff, 0xea, 0x17, - 0xd5, 0x0c, 0xe6, 0x37, 0xd3, 0x46, 0x70, 0xbf, 0x55, 0x74, 0x0d, 0xe6, 0xda, 0x96, 0x63, 0xb5, - 0x3b, 0xed, 0x3b, 0xd4, 0xe7, 0xac, 0xad, 0xbc, 0x45, 0xbd, 0xee, 0xea, 0xdc, 0x4e, 0xaa, 0x07, - 0xf7, 0x69, 0x22, 0x13, 0xa6, 0x5c, 0x2f, 0xb9, 0xef, 0xd6, 0xc7, 0x38, 0xa7, 0x8c, 0xdb, 0x72, - 0xa8, 0xac, 0x74, 0x23, 0x3a, 0x54, 0x52, 0x1c, 0x22, 0x2f, 0x5f, 0x83, 0x99, 0xa4, 0xe6, 0x58, - 0xd5, 0xe6, 0x3f, 0x73, 0x50, 0xaa, 0x9b, 0xde, 0xff, 0xc6, 0x6b, 0xcd, 0x6e, 0xea, 0xb5, 0x26, - 0xc3, 0x4f, 0x59, 0xa1, 0xe7, 0x43, 0x1f, 0x6b, 0xde, 0xea, 0x7b, 0xac, 0xb9, 0x38, 0x06, 0xe6, - 0xf1, 0x6f, 0x35, 0xbf, 0xcc, 0xc1, 0x4c, 0xa8, 0x7a, 0xe2, 0x2f, 0xad, 0xb7, 0xd3, 0x97, 0xd6, - 0xf3, 0xd9, 0xa3, 0x34, 0xe4, 0xce, 0x3a, 0x17, 0x07, 0x87, 0xaf, 0x86, 0xbe, 0x00, 0x73, 0xe9, - 0xb8, 0x8a, 0xff, 0x1f, 0xd4, 0x7d, 0xd2, 0x6c, 0x5a, 0x66, 0xcd, 0xb3, 0x2d, 0x76, 0xe2, 0x93, - 0xb7, 0x9e, 0x4a, 0xde, 0x0c, 0x4f, 0x56, 0x49, 0xef, 0x33, 0xfc, 0xff, 0xa0, 0x90, 0xf5, 0xff, - 0x07, 0x29, 0xdc, 0xe3, 0x93, 0xf8, 0xa3, 0x1c, 0x2c, 0x24, 0xd5, 0x4f, 0x7c, 0x22, 0xd7, 0xd2, - 0x89, 0x6c, 0x8c, 0x17, 0xad, 0x21, 0xc9, 0x8c, 0xd2, 0x41, 0x12, 0x09, 0x7d, 0x0a, 0xd0, 0x11, - 0x71, 0x36, 0x1e, 0x3e, 0x5a, 0x99, 0xf8, 0xf8, 0xd1, 0xca, 0xc4, 0x27, 0x8f, 0x56, 0x26, 0xde, - 0xeb, 0xad, 0x68, 0x0f, 0x7b, 0x2b, 0xda, 0xc7, 0xbd, 0x15, 0xed, 0x93, 0xde, 0x8a, 0xf6, 0xc7, - 0xde, 0x8a, 0xf6, 0xc1, 0x9f, 0x56, 0x26, 0xde, 0x29, 0x85, 0xc6, 0xff, 0x1d, 0x00, 0x00, 0xff, - 0xff, 0x96, 0x00, 0x14, 0x99, 0xb9, 0x27, 0x00, 0x00, + // 2249 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0xcf, 0x6f, 0x1c, 0x49, + 0xf5, 0x4f, 0xcf, 0x0f, 0x7b, 0xe6, 0xf9, 0x77, 0x7d, 0xb3, 0xf9, 0x7a, 0xcd, 0xca, 0x63, 0x75, + 0x58, 0x44, 0xc2, 0xa6, 0x27, 0xf1, 0x86, 0xe0, 0x84, 0x70, 0xf0, 0x78, 0x93, 0x18, 0xc9, 0x4e, + 0xbc, 0xe5, 0x21, 0x6c, 0x96, 0x68, 0xa1, 0xdc, 0x53, 0x33, 0x6e, 0xdc, 0xd3, 0xdd, 0xea, 0xae, + 0x71, 0xb0, 0x04, 0xd2, 0x92, 0xcb, 0x5e, 0x17, 0x6e, 0xcb, 0x8f, 0xd3, 0x5e, 0xf9, 0x17, 0x38, + 0x13, 0x71, 0xda, 0xe3, 0x8a, 0xc3, 0x88, 0x0c, 0x42, 0x7b, 0x40, 0x08, 0xc4, 0x0a, 0x24, 0x7c, + 0x42, 0xf5, 0xa3, 0x7f, 0xcd, 0x78, 0xec, 0x9e, 0x25, 0xd9, 0x60, 0xc4, 0xad, 0xab, 0xea, 0xd5, + 0xe7, 0xd5, 0x7b, 0xf5, 0xea, 0x53, 0xaf, 0xde, 0x0c, 0x7c, 0x35, 0xb0, 0x5a, 0x81, 0xb1, 0xb7, + 0x12, 0x18, 0x96, 0x5b, 0x0d, 0xa8, 0xbf, 0x6f, 0x99, 0xf4, 0x12, 0xf1, 0xac, 0xa0, 0x4a, 0x3c, + 0xab, 0xba, 0x7f, 0x85, 0xd8, 0xde, 0x2e, 0xb9, 0x52, 0x6d, 0x51, 0x87, 0xfa, 0x84, 0xd1, 0x86, + 0xe1, 0xf9, 0x2e, 0x73, 0xd1, 0x92, 0x9c, 0x61, 0xa8, 0x19, 0xdf, 0xe5, 0x33, 0x0c, 0xe2, 0x59, + 0x46, 0x38, 0x63, 0xe1, 0x52, 0xcb, 0x62, 0xbb, 0x9d, 0x1d, 0xc3, 0x74, 0xdb, 0xd5, 0x96, 0xdb, + 0x72, 0xab, 0x62, 0xe2, 0x4e, 0xa7, 0x29, 0x5a, 0xa2, 0x21, 0xbe, 0x24, 0xe0, 0x82, 0xae, 0x96, + 0xc0, 0xb5, 0x9a, 0xae, 0x4f, 0xab, 0xfb, 0x03, 0x4a, 0x17, 0xae, 0xc6, 0x32, 0x6d, 0x62, 0xee, + 0x5a, 0x0e, 0xf5, 0x0f, 0xaa, 0xde, 0x5e, 0xab, 0x2a, 0xd6, 0xdb, 0xa6, 0x8c, 0x1c, 0x35, 0xeb, + 0xda, 0xb0, 0x59, 0x7e, 0xc7, 0x61, 0x56, 0x9b, 0x56, 0x03, 0x73, 0x97, 0xb6, 0xc9, 0xc0, 0xbc, + 0xeb, 0x49, 0xcf, 0x98, 0xae, 0xc3, 0x7c, 0xd7, 0xb6, 0xa9, 0x7f, 0x29, 0x9c, 0xc6, 0x21, 0xc4, + 0x54, 0xda, 0x3f, 0x55, 0xff, 0x85, 0x06, 0xaf, 0xae, 0xb9, 0x4e, 0xd3, 0x6a, 0x6d, 0x12, 0x2f, + 0x78, 0x83, 0x36, 0x49, 0xc7, 0x66, 0x1b, 0xae, 0x49, 0xec, 0x7b, 0x3b, 0xdf, 0xa7, 0x26, 0xc3, + 0xb4, 0x49, 0x7d, 0xea, 0x98, 0x14, 0x9d, 0x87, 0x62, 0xcb, 0x77, 0x3b, 0xde, 0xbc, 0xb6, 0xa4, + 0x7d, 0xb9, 0x5c, 0x9b, 0x7a, 0xd2, 0xad, 0x9c, 0xe9, 0x75, 0x2b, 0xc5, 0x3b, 0xbc, 0x13, 0xcb, + 0x31, 0xf4, 0x1a, 0x94, 0x7c, 0x1a, 0xb8, 0x1d, 0xdf, 0xa4, 0xf3, 0x39, 0x21, 0x37, 0xab, 0xe4, + 0x4a, 0x58, 0xf5, 0xe3, 0x48, 0x02, 0x2d, 0x41, 0xc1, 0x21, 0x6d, 0x3a, 0x9f, 0x17, 0x92, 0x93, + 0x4a, 0xb2, 0x70, 0x97, 0xb4, 0x29, 0x16, 0x23, 0xfa, 0x6f, 0x34, 0x98, 0xb9, 0xed, 0xfa, 0x8f, + 0x88, 0xdf, 0xa8, 0xbb, 0x75, 0xe2, 0xb7, 0x28, 0x43, 0xfb, 0x50, 0x66, 0xe2, 0x0b, 0xd3, 0xa6, + 0x58, 0xcc, 0xc4, 0xf2, 0x2d, 0xe3, 0xa4, 0x4d, 0x36, 0xb6, 0xe5, 0xc8, 0x71, 0x26, 0xd6, 0xe6, + 0xd4, 0x0a, 0xca, 0xf5, 0x10, 0x1f, 0xc7, 0xaa, 0xd0, 0x4d, 0x00, 0xd9, 0xd8, 0x72, 0x7d, 0x26, + 0xac, 0x2b, 0xd6, 0x5e, 0xe9, 0x75, 0x2b, 0x50, 0x8f, 0x7a, 0x0f, 0x53, 0x2d, 0x9c, 0x90, 0xd7, + 0x3f, 0xcd, 0xc1, 0xf8, 0x1d, 0xc2, 0xe8, 0x23, 0x72, 0x80, 0x1e, 0x42, 0x89, 0x1d, 0x78, 0x74, + 0x93, 0x32, 0xa2, 0x0c, 0x30, 0x42, 0x03, 0x92, 0x5b, 0x6f, 0x78, 0x7b, 0x2d, 0x43, 0x58, 0xc2, + 0x03, 0xc6, 0xd8, 0xbf, 0x62, 0xd4, 0xd5, 0xac, 0xd8, 0xab, 0x61, 0x0f, 0x8e, 0x10, 0xd1, 0xf7, + 0xa0, 0xc4, 0xe5, 0x1b, 0x84, 0x11, 0xb1, 0xca, 0x89, 0xe5, 0xcb, 0xd9, 0xd0, 0xa5, 0x3b, 0x04, + 0x3e, 0x52, 0xf8, 0x10, 0xf7, 0xe1, 0x08, 0x15, 0xdd, 0x83, 0x42, 0xe0, 0x51, 0x53, 0xec, 0xdb, + 0xc4, 0xf2, 0xa5, 0x93, 0x9d, 0xaf, 0x0c, 0xdf, 0xf6, 0xa8, 0x19, 0x6f, 0x33, 0x6f, 0x61, 0x01, + 0x84, 0xbe, 0x0d, 0x63, 0x01, 0x23, 0xac, 0x13, 0xcc, 0x17, 0x04, 0x64, 0x35, 0x3b, 0xa4, 0x98, + 0x56, 0x9b, 0x56, 0xa0, 0x63, 0xb2, 0x8d, 0x15, 0x9c, 0xfe, 0x38, 0x0f, 0x93, 0x4a, 0x72, 0xcd, + 0x26, 0x41, 0x90, 0x72, 0x7d, 0xe1, 0xb9, 0xba, 0x5e, 0x7b, 0x2e, 0xae, 0xaf, 0x2b, 0xd7, 0xcb, + 0x8d, 0x5d, 0xce, 0xec, 0x27, 0x61, 0xfd, 0x50, 0xff, 0x3f, 0x8c, 0xfc, 0x2f, 0xb7, 0xf4, 0xea, + 0x88, 0xb8, 0xc7, 0x6f, 0xc2, 0x5f, 0x72, 0xf0, 0x52, 0x52, 0x7c, 0xcd, 0x75, 0x1a, 0x16, 0xb3, + 0x5c, 0x07, 0x7d, 0x03, 0x0a, 0xdc, 0x77, 0x8a, 0x52, 0x2e, 0x84, 0x2b, 0xe3, 0x9e, 0x3d, 0xec, + 0x56, 0x5e, 0x3e, 0x72, 0x12, 0x1f, 0xc4, 0x62, 0x1a, 0xda, 0x88, 0x96, 0x2d, 0xb9, 0xe6, 0x6a, + 0x7a, 0x01, 0x87, 0xdd, 0xca, 0x11, 0x5c, 0x6d, 0x44, 0x48, 0xe9, 0x65, 0xa2, 0x2f, 0xc1, 0x98, + 0x4f, 0x49, 0xe0, 0x3a, 0x8a, 0x8f, 0x22, 0x73, 0xb0, 0xe8, 0xc5, 0x6a, 0x14, 0x5d, 0x80, 0xf1, + 0x36, 0x0d, 0x02, 0xd2, 0xa2, 0x22, 0x82, 0xca, 0xb5, 0x19, 0x25, 0x38, 0xbe, 0x29, 0xbb, 0x71, + 0x38, 0x8e, 0xf6, 0x01, 0xd9, 0x24, 0x60, 0x75, 0x9f, 0x38, 0x81, 0x5c, 0xbc, 0xd5, 0xa6, 0xf3, + 0x45, 0xe1, 0xe3, 0x8b, 0x19, 0xe3, 0xce, 0x6a, 0xd3, 0xda, 0x82, 0xd2, 0x80, 0x36, 0x06, 0xd0, + 0xf0, 0x11, 0x1a, 0xf4, 0x0f, 0x73, 0x30, 0x9b, 0x74, 0xde, 0x86, 0x15, 0xb0, 0x54, 0xe8, 0xe7, + 0x9f, 0x79, 0xe8, 0x3f, 0x1c, 0x08, 0xfd, 0x8c, 0xe8, 0x7c, 0x6d, 0x69, 0xf4, 0xb0, 0x27, 0x11, + 0xf6, 0xdb, 0x50, 0xb4, 0x18, 0x6d, 0xf3, 0x8d, 0xce, 0x27, 0xa1, 0xb3, 0xc5, 0x67, 0x7c, 0x59, + 0x7d, 0x93, 0x83, 0x60, 0x89, 0xa5, 0x7f, 0x92, 0x4f, 0x7b, 0x89, 0x1f, 0x08, 0xb4, 0x0c, 0x10, + 0xdf, 0xa0, 0x2a, 0x30, 0xa3, 0x23, 0xb9, 0x16, 0x8d, 0xe0, 0x84, 0x14, 0xfa, 0x89, 0x06, 0xf3, + 0xc4, 0xb6, 0xdd, 0x47, 0xb4, 0xa1, 0xf0, 0xf8, 0x15, 0x16, 0x78, 0xc4, 0xa4, 0x81, 0x3a, 0xa9, + 0xaf, 0x67, 0x74, 0x06, 0xd9, 0xa1, 0xf6, 0x36, 0xb5, 0xa9, 0xc9, 0x5c, 0xbf, 0xb6, 0xa4, 0xf4, + 0xce, 0xaf, 0x0e, 0x01, 0xc7, 0x43, 0xd5, 0xa2, 0xf7, 0x34, 0x38, 0xa7, 0x06, 0xb1, 0xdb, 0x61, + 0x34, 0xb1, 0xa2, 0xfc, 0x67, 0x5f, 0xd1, 0x42, 0xaf, 0x5b, 0x39, 0xb7, 0x7a, 0x24, 0x2c, 0x1e, + 0xa2, 0x0e, 0xbd, 0xab, 0xc1, 0x94, 0x47, 0x7c, 0xd2, 0xa6, 0x8c, 0xfa, 0x01, 0xbf, 0xb4, 0x25, + 0xf1, 0xde, 0x39, 0x79, 0x13, 0x33, 0x65, 0x26, 0xb5, 0xb9, 0x5e, 0xb7, 0x32, 0xb5, 0x95, 0xd4, + 0x80, 0xd3, 0x0a, 0xf5, 0x1f, 0x6b, 0x80, 0x06, 0x09, 0x0b, 0xed, 0x89, 0xbd, 0x96, 0x64, 0x10, + 0xcc, 0x6b, 0x22, 0xb4, 0xbe, 0x36, 0x5a, 0x68, 0x45, 0x64, 0x92, 0x0a, 0x12, 0x05, 0x89, 0x13, + 0xf0, 0xfa, 0x1f, 0x13, 0x67, 0x32, 0x22, 0xc0, 0x95, 0x14, 0x01, 0x7e, 0xb1, 0x8f, 0x00, 0xcf, + 0xf6, 0xcb, 0x3f, 0x37, 0xee, 0x4b, 0x70, 0x5a, 0xfe, 0x04, 0x4e, 0x8b, 0x69, 0xb2, 0x70, 0x2c, + 0x4d, 0xbe, 0x28, 0xee, 0xfb, 0x20, 0x07, 0x13, 0xca, 0x6f, 0x03, 0xb4, 0xa7, 0x3d, 0x57, 0xda, + 0xcb, 0x3d, 0x73, 0xda, 0xbb, 0x1b, 0xd2, 0x5e, 0x5e, 0xc4, 0xe6, 0x85, 0xcc, 0xb1, 0x39, 0x84, + 0xf1, 0xf6, 0xe0, 0x9c, 0x12, 0xe8, 0xcf, 0xee, 0xab, 0x50, 0x76, 0xc2, 0x23, 0xab, 0xa2, 0x31, + 0xca, 0x86, 0xa3, 0xb3, 0x8c, 0x63, 0x99, 0x28, 0x77, 0xcf, 0x0d, 0xcd, 0xdd, 0x3f, 0xd5, 0xa2, + 0x8d, 0x10, 0xcc, 0x7a, 0x1e, 0x8a, 0x26, 0x3f, 0x32, 0xfd, 0x0f, 0x08, 0x71, 0x8e, 0xb0, 0x1c, + 0x43, 0xdf, 0x81, 0xb2, 0x6d, 0x05, 0x8c, 0xbf, 0x52, 0x42, 0xb2, 0xbf, 0x78, 0xb2, 0xd5, 0x1b, + 0x6a, 0x4a, 0xbc, 0xe6, 0xb0, 0x27, 0xc0, 0x31, 0x1e, 0xda, 0x81, 0x32, 0x75, 0x1a, 0x9e, 0x6b, + 0x39, 0x2c, 0x74, 0xe9, 0x95, 0xec, 0xe0, 0xab, 0x8d, 0x86, 0x4f, 0x83, 0x20, 0xd6, 0xa1, 0x3a, + 0x68, 0x80, 0x63, 0x58, 0xfd, 0x77, 0x1a, 0x4c, 0xa5, 0x72, 0x53, 0xd4, 0x3c, 0x82, 0x65, 0x46, + 0x48, 0xdc, 0xb2, 0x12, 0x0c, 0x22, 0x83, 0xae, 0xbb, 0x9c, 0xdd, 0x3a, 0x95, 0xc3, 0x1d, 0xeb, + 0x40, 0xfd, 0xb7, 0x1a, 0xcc, 0xae, 0xd7, 0xeb, 0x5b, 0xeb, 0x94, 0x34, 0xa8, 0x7f, 0xdb, 0xb2, + 0x19, 0xf5, 0xd1, 0xdb, 0x90, 0x27, 0x8d, 0x86, 0x32, 0xec, 0xeb, 0x27, 0x6b, 0xec, 0x07, 0x30, + 0x56, 0x1b, 0x8d, 0x5b, 0x0e, 0xf3, 0x0f, 0x6a, 0x13, 0x4a, 0x79, 0x7e, 0xb5, 0xd1, 0xc0, 0x1c, + 0x14, 0xe9, 0x9c, 0x6c, 0xda, 0xee, 0x3e, 0x15, 0x06, 0x95, 0x6b, 0x20, 0x89, 0x86, 0xf7, 0x60, + 0x35, 0xb2, 0x70, 0x0d, 0x4a, 0x21, 0x02, 0x9a, 0x85, 0xfc, 0x1e, 0x3d, 0x90, 0x11, 0x86, 0xf9, + 0x27, 0x3a, 0x0b, 0xc5, 0x7d, 0x62, 0x77, 0x54, 0xa0, 0x62, 0xd9, 0xb8, 0x91, 0x5b, 0xd1, 0xf4, + 0x7f, 0xe6, 0xa0, 0xcc, 0xd7, 0x22, 0xee, 0xab, 0x53, 0xff, 0x26, 0x7b, 0x33, 0xf5, 0x26, 0xab, + 0x66, 0xdb, 0x06, 0x61, 0xfa, 0xd0, 0x57, 0xc1, 0x83, 0xbe, 0x57, 0xd9, 0x95, 0x51, 0x40, 0x8f, + 0x7f, 0x12, 0xfc, 0x55, 0x83, 0x99, 0x48, 0x76, 0xd5, 0x14, 0x77, 0xe1, 0x3b, 0x50, 0x6e, 0x86, + 0x4f, 0x7d, 0xb5, 0x05, 0x19, 0x34, 0xf6, 0x55, 0x07, 0x6a, 0x53, 0x3c, 0x78, 0xa3, 0x4e, 0x1c, + 0x43, 0xa2, 0x1f, 0xc1, 0x24, 0xfd, 0x01, 0xa3, 0x4e, 0x60, 0xb9, 0x0e, 0xcf, 0x42, 0x72, 0xcf, + 0x36, 0x0b, 0x99, 0xed, 0x75, 0x2b, 0x93, 0xb7, 0x12, 0x0a, 0x70, 0x4a, 0x9d, 0xfe, 0xa7, 0xa4, + 0xc9, 0xea, 0xe8, 0x3c, 0x80, 0xf1, 0x5d, 0x71, 0x12, 0x02, 0x65, 0xf0, 0xf2, 0xe8, 0xc7, 0xa7, + 0x36, 0xc1, 0xaf, 0x69, 0xd9, 0x13, 0xe0, 0x10, 0xef, 0x45, 0x5b, 0xfb, 0xd3, 0x1c, 0x4c, 0x45, + 0xd6, 0xae, 0xbb, 0x01, 0x43, 0xaf, 0x41, 0x69, 0xd7, 0x0d, 0x98, 0xb8, 0x34, 0xb4, 0x74, 0x69, + 0x68, 0x5d, 0xf5, 0xe3, 0x48, 0x02, 0xd5, 0xa1, 0xe8, 0x77, 0x6c, 0x1a, 0x12, 0xd9, 0x28, 0xf1, + 0x8c, 0x3b, 0x36, 0x8d, 0x6f, 0x17, 0xde, 0x0a, 0xb0, 0x04, 0x1b, 0x70, 0x4a, 0xfe, 0xf3, 0x75, + 0xca, 0x2f, 0x93, 0x4e, 0x39, 0xf5, 0xc9, 0xc9, 0x56, 0x3a, 0x39, 0xf9, 0xca, 0x08, 0x5b, 0x34, + 0x24, 0x3d, 0xf9, 0x55, 0x1e, 0xa6, 0x23, 0x99, 0x4d, 0xc2, 0xcc, 0x5d, 0x1e, 0x35, 0x1e, 0x61, + 0xbb, 0xf5, 0x38, 0x49, 0x8e, 0x96, 0xb4, 0xa5, 0xfa, 0x71, 0x24, 0x81, 0x5e, 0x81, 0x02, 0xff, + 0x56, 0x49, 0x49, 0x89, 0xf3, 0x19, 0x97, 0xc2, 0xa2, 0x17, 0x19, 0x00, 0xf2, 0x74, 0x08, 0x34, + 0xf5, 0xc8, 0xe7, 0x84, 0xba, 0x1e, 0xf5, 0xe2, 0x84, 0x04, 0x6a, 0xc0, 0x98, 0x6c, 0xcd, 0x17, + 0x84, 0x85, 0x37, 0x47, 0xb0, 0x50, 0xac, 0xde, 0x90, 0xc0, 0xf2, 0x72, 0x8b, 0xa8, 0x50, 0x76, + 0x62, 0x85, 0x3d, 0x10, 0x93, 0xc5, 0xcf, 0x35, 0x26, 0x17, 0xae, 0xc3, 0x44, 0x62, 0x95, 0x23, + 0x5d, 0xa0, 0xef, 0x27, 0xc3, 0x99, 0x9f, 0x33, 0xf4, 0x26, 0x14, 0xdb, 0xdc, 0xf0, 0xfe, 0xe2, + 0x57, 0x56, 0x87, 0xd5, 0xca, 0x3c, 0x26, 0xc4, 0x27, 0x96, 0x48, 0xe8, 0x5b, 0x30, 0xd6, 0x14, + 0x3c, 0xa7, 0x22, 0x78, 0x94, 0x4b, 0x48, 0x11, 0xa4, 0x48, 0x1a, 0xe4, 0x37, 0x56, 0x60, 0x1c, + 0x96, 0x88, 0x6b, 0x47, 0x71, 0xc0, 0x28, 0xb0, 0xf2, 0xbe, 0x92, 0xb0, 0xf2, 0x1b, 0x2b, 0x30, + 0xfd, 0xd7, 0x5a, 0xc2, 0x25, 0x22, 0xeb, 0xad, 0x43, 0x91, 0x93, 0x5a, 0x98, 0xf8, 0x8d, 0x42, + 0x64, 0x9c, 0x16, 0xe3, 0x93, 0xc2, 0x5b, 0x01, 0x96, 0x60, 0xe8, 0x3e, 0x8c, 0x37, 0xe4, 0xa6, + 0x2b, 0xb7, 0x8c, 0x8c, 0x2b, 0x6e, 0x0d, 0x15, 0x38, 0x38, 0x04, 0xd3, 0x1f, 0x27, 0x2f, 0x29, + 0x95, 0xbf, 0xba, 0x30, 0xd1, 0x92, 0xb9, 0x28, 0xa6, 0xcd, 0xd0, 0x8e, 0x95, 0xcc, 0x09, 0x6c, + 0x7f, 0x40, 0xfe, 0x9f, 0x32, 0x28, 0x7c, 0x1b, 0x70, 0x50, 0x9c, 0xd4, 0xa0, 0x3b, 0x30, 0x15, + 0xde, 0x08, 0x92, 0x04, 0x56, 0x92, 0x61, 0x55, 0xae, 0xe9, 0xa1, 0x4b, 0xc4, 0xe8, 0x61, 0xb7, + 0x32, 0x97, 0x12, 0x17, 0xe7, 0x58, 0x45, 0xcf, 0xf9, 0x54, 0xf0, 0xc6, 0xce, 0xbc, 0xcf, 0x3b, + 0x55, 0x2c, 0xeb, 0x7f, 0xce, 0x41, 0x29, 0x4c, 0x77, 0xd1, 0x83, 0xbe, 0x6b, 0x2a, 0x9b, 0x6b, + 0x93, 0xfa, 0x6b, 0x93, 0x43, 0xee, 0xb4, 0x25, 0x28, 0x78, 0xf1, 0x4f, 0x07, 0x51, 0xc6, 0x25, + 0x7e, 0x2a, 0x10, 0x23, 0xe8, 0x26, 0x94, 0xc4, 0xcf, 0x32, 0xa6, 0x6b, 0x2b, 0x7e, 0x5a, 0x8a, + 0xd8, 0x4e, 0xf5, 0x1f, 0x76, 0x2b, 0x93, 0xe1, 0xb7, 0x62, 0x3f, 0xd5, 0x42, 0xb7, 0x21, 0xcf, + 0xec, 0x30, 0x59, 0xcb, 0x40, 0xc7, 0xf5, 0x8d, 0x6d, 0xc9, 0x21, 0xb5, 0x71, 0x9e, 0x74, 0xd7, + 0x37, 0xb6, 0x31, 0x07, 0x40, 0xef, 0xc0, 0x98, 0xcf, 0xf7, 0x3f, 0x50, 0x5c, 0x74, 0xed, 0x64, + 0x28, 0xc9, 0xea, 0x96, 0xd3, 0xb0, 0x9c, 0x56, 0x54, 0x2c, 0x8a, 0x2b, 0x03, 0x02, 0x0d, 0x2b, + 0x54, 0xbd, 0x05, 0x33, 0x7d, 0x6f, 0x2a, 0x54, 0x4d, 0xd5, 0x41, 0xbe, 0xd0, 0x57, 0x07, 0x99, + 0x50, 0x62, 0x89, 0xf2, 0x47, 0xa6, 0x8d, 0xfd, 0x24, 0x07, 0x73, 0xa1, 0xa6, 0xb8, 0xe6, 0x72, + 0x3d, 0xa5, 0xeb, 0xd5, 0x3e, 0x5d, 0x2f, 0x0d, 0x4c, 0xf8, 0x5f, 0xd1, 0xe5, 0xe4, 0xa2, 0xcb, + 0xdf, 0x35, 0x98, 0x4e, 0xbf, 0x24, 0xa3, 0x02, 0x81, 0x36, 0xac, 0x40, 0x80, 0xde, 0x82, 0x71, + 0x22, 0x37, 0x36, 0x3b, 0xb7, 0xf7, 0x3f, 0xc6, 0x05, 0x8d, 0xa9, 0x06, 0x0e, 0xe1, 0x50, 0x2b, + 0xf5, 0xe4, 0x96, 0xf9, 0xc9, 0xeb, 0xd9, 0xc1, 0xb3, 0x17, 0xf5, 0x1e, 0xe7, 0xe0, 0xec, 0x51, + 0xb1, 0x8f, 0x7e, 0x08, 0x73, 0x51, 0xad, 0x24, 0xec, 0x54, 0x7c, 0xf2, 0x99, 0x0a, 0xaf, 0x2f, + 0xab, 0x85, 0xcc, 0xdd, 0xed, 0x47, 0xc5, 0x83, 0x8a, 0x90, 0x0d, 0x53, 0xe2, 0xac, 0x45, 0x9a, + 0xff, 0x8d, 0x22, 0xb4, 0xa8, 0xae, 0xe2, 0x24, 0x1a, 0x4e, 0x83, 0xeb, 0x1f, 0x68, 0xa0, 0x6f, + 0x53, 0xd3, 0xa7, 0xec, 0x3f, 0xef, 0x07, 0xe4, 0x9f, 0x69, 0x70, 0x3e, 0xc3, 0x4f, 0xbf, 0x2f, + 0x66, 0x71, 0x7f, 0xcb, 0x41, 0x39, 0x22, 0x61, 0xf4, 0x9e, 0x06, 0x33, 0x26, 0xf5, 0x99, 0xd5, + 0xb4, 0x4c, 0xc2, 0x68, 0xe2, 0xb2, 0x7d, 0x23, 0xcb, 0xcf, 0xdb, 0x27, 0xf9, 0xbf, 0xf6, 0xff, + 0x6a, 0x05, 0x33, 0x6b, 0x69, 0x25, 0xb8, 0x5f, 0x2b, 0xba, 0x01, 0xd3, 0x6d, 0xcb, 0xb1, 0xda, + 0x9d, 0xf6, 0x7d, 0xea, 0xf3, 0x44, 0x51, 0x59, 0x8b, 0x7a, 0xdd, 0xca, 0xf4, 0x66, 0x6a, 0x04, + 0xf7, 0x49, 0x22, 0x13, 0xc6, 0x5d, 0x2f, 0x79, 0xee, 0x56, 0x46, 0xb8, 0x88, 0x8c, 0x7b, 0x72, + 0xaa, 0xcc, 0x98, 0x23, 0x3a, 0x54, 0xbd, 0x38, 0x44, 0x5e, 0xb8, 0x01, 0x93, 0x49, 0xc9, 0x91, + 0xb2, 0xd6, 0x7f, 0xe4, 0xa0, 0x54, 0x37, 0xbd, 0xff, 0x8e, 0xaa, 0xcf, 0x56, 0xaa, 0xea, 0x93, + 0xe1, 0x67, 0xb1, 0xd0, 0xf2, 0xa1, 0x45, 0x9f, 0xb7, 0xfa, 0x8a, 0x3e, 0x97, 0x47, 0xc0, 0x3c, + 0xbe, 0xe6, 0xf3, 0xf3, 0x1c, 0x4c, 0x86, 0xa2, 0xa7, 0xfe, 0xf1, 0x7b, 0x2f, 0xfd, 0xf8, 0xbd, + 0x98, 0xdd, 0x4b, 0x43, 0xde, 0xbe, 0xd3, 0xb1, 0x73, 0xf8, 0x6e, 0xe8, 0xb3, 0x30, 0x9d, 0xf6, + 0xab, 0xf8, 0x2f, 0x43, 0xdd, 0x27, 0xcd, 0xa6, 0x65, 0x6e, 0x7b, 0xb6, 0xc5, 0x4e, 0x7d, 0xf0, + 0xd6, 0x53, 0xc1, 0x9b, 0xa1, 0xf4, 0x95, 0xb4, 0x3e, 0xc3, 0x7f, 0x19, 0x0a, 0x59, 0xff, 0xcb, + 0x90, 0xc2, 0x3d, 0x3e, 0x88, 0x3f, 0xcc, 0xc1, 0x6c, 0x52, 0xfc, 0xd4, 0x07, 0xf2, 0x76, 0x3a, + 0x90, 0x8d, 0xd1, 0xbc, 0x35, 0x24, 0x98, 0x51, 0xda, 0x49, 0x22, 0xa0, 0xcf, 0x02, 0x3a, 0xc2, + 0xcf, 0xc6, 0x93, 0xa7, 0x8b, 0x67, 0x3e, 0x7a, 0xba, 0x78, 0xe6, 0xe3, 0xa7, 0x8b, 0x67, 0xde, + 0xed, 0x2d, 0x6a, 0x4f, 0x7a, 0x8b, 0xda, 0x47, 0xbd, 0x45, 0xed, 0xe3, 0xde, 0xa2, 0xf6, 0xfb, + 0xde, 0xa2, 0xf6, 0xfe, 0x1f, 0x16, 0xcf, 0xbc, 0x5d, 0x0a, 0x95, 0xff, 0x2b, 0x00, 0x00, 0xff, + 0xff, 0x45, 0xc9, 0x47, 0xfe, 0x05, 0x28, 0x00, 0x00, } func (m *ConfigMapsDefaultLocalObjectReference) Marshal() (dAtA []byte, err error) { @@ -1902,16 +1935,20 @@ func (m *GatewaySpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - { - size, err := m.Routes.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if len(m.Addresses) > 0 { + for iNdEx := len(m.Addresses) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Addresses[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i-- - dAtA[i] = 0x1a if len(m.Listeners) > 0 { for iNdEx := len(m.Listeners) - 1; iNdEx >= 0; iNdEx-- { { @@ -2532,6 +2569,39 @@ func (m *HTTPRouteStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *HostnameMatch) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *HostnameMatch) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HostnameMatch) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Value) + copy(dAtA[i:], m.Value) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Value))) + i-- + dAtA[i] = 0x12 + i -= len(m.Match) + copy(dAtA[i:], m.Match) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Match))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *Listener) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2552,18 +2622,16 @@ func (m *Listener) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.ExtensionRef != nil { - { - size, err := m.ExtensionRef.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + { + size, err := m.Routes.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } - i-- - dAtA[i] = 0x32 + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0x2a if m.TLS != nil { { size, err := m.TLS.MarshalToSizedBuffer(dAtA[:i]) @@ -2574,23 +2642,19 @@ func (m *Listener) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenerated(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x2a - } - if m.Protocol != nil { - i -= len(*m.Protocol) - copy(dAtA[i:], *m.Protocol) - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Protocol))) - i-- dAtA[i] = 0x22 } - if m.Port != nil { - i = encodeVarintGenerated(dAtA, i, uint64(*m.Port)) - i-- - dAtA[i] = 0x18 - } - if m.Address != nil { + i -= len(m.Protocol) + copy(dAtA[i:], m.Protocol) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Protocol))) + i-- + dAtA[i] = 0x1a + i = encodeVarintGenerated(dAtA, i, uint64(m.Port)) + i-- + dAtA[i] = 0x10 + if m.Hostname != nil { { - size, err := m.Address.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Hostname.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -2598,13 +2662,8 @@ func (m *Listener) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenerated(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x12 + dAtA[i] = 0xa } - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0xa return len(dAtA) - i, nil } @@ -3482,8 +3541,12 @@ func (m *GatewaySpec) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } - l = m.Routes.Size() - n += 1 + l + sovGenerated(uint64(l)) + if len(m.Addresses) > 0 { + for _, e := range m.Addresses { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -3708,33 +3771,38 @@ func (m *HTTPRouteStatus) Size() (n int) { return n } -func (m *Listener) Size() (n int) { +func (m *HostnameMatch) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.Name) + l = len(m.Match) n += 1 + l + sovGenerated(uint64(l)) - if m.Address != nil { - l = m.Address.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.Port != nil { - n += 1 + sovGenerated(uint64(*m.Port)) + l = len(m.Value) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *Listener) Size() (n int) { + if m == nil { + return 0 } - if m.Protocol != nil { - l = len(*m.Protocol) + var l int + _ = l + if m.Hostname != nil { + l = m.Hostname.Size() n += 1 + l + sovGenerated(uint64(l)) } + n += 1 + sovGenerated(uint64(m.Port)) + l = len(m.Protocol) + n += 1 + l + sovGenerated(uint64(l)) if m.TLS != nil { l = m.TLS.Size() n += 1 + l + sovGenerated(uint64(l)) } - if m.ExtensionRef != nil { - l = m.ExtensionRef.Size() - n += 1 + l + sovGenerated(uint64(l)) - } + l = m.Routes.Size() + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -4136,10 +4204,15 @@ func (this *GatewaySpec) String() string { repeatedStringForListeners += strings.Replace(strings.Replace(f.String(), "Listener", "Listener", 1), `&`, ``, 1) + "," } repeatedStringForListeners += "}" + repeatedStringForAddresses := "[]ListenerAddress{" + for _, f := range this.Addresses { + repeatedStringForAddresses += strings.Replace(strings.Replace(f.String(), "ListenerAddress", "ListenerAddress", 1), `&`, ``, 1) + "," + } + repeatedStringForAddresses += "}" s := strings.Join([]string{`&GatewaySpec{`, `Class:` + fmt.Sprintf("%v", this.Class) + `,`, `Listeners:` + repeatedStringForListeners + `,`, - `Routes:` + strings.Replace(strings.Replace(this.Routes.String(), "RouteBindingSelector", "RouteBindingSelector", 1), `&`, ``, 1) + `,`, + `Addresses:` + repeatedStringForAddresses + `,`, `}`, }, "") return s @@ -4322,17 +4395,27 @@ func (this *HTTPRouteStatus) String() string { }, "") return s } +func (this *HostnameMatch) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&HostnameMatch{`, + `Match:` + fmt.Sprintf("%v", this.Match) + `,`, + `Value:` + fmt.Sprintf("%v", this.Value) + `,`, + `}`, + }, "") + return s +} func (this *Listener) String() string { if this == nil { return "nil" } s := strings.Join([]string{`&Listener{`, - `Name:` + fmt.Sprintf("%v", this.Name) + `,`, - `Address:` + strings.Replace(this.Address.String(), "ListenerAddress", "ListenerAddress", 1) + `,`, - `Port:` + valueToStringGenerated(this.Port) + `,`, - `Protocol:` + valueToStringGenerated(this.Protocol) + `,`, + `Hostname:` + strings.Replace(this.Hostname.String(), "HostnameMatch", "HostnameMatch", 1) + `,`, + `Port:` + fmt.Sprintf("%v", this.Port) + `,`, + `Protocol:` + fmt.Sprintf("%v", this.Protocol) + `,`, `TLS:` + strings.Replace(this.TLS.String(), "TLSConfig", "TLSConfig", 1) + `,`, - `ExtensionRef:` + strings.Replace(this.ExtensionRef.String(), "ConfigMapsDefaultLocalObjectReference", "ConfigMapsDefaultLocalObjectReference", 1) + `,`, + `Routes:` + strings.Replace(strings.Replace(this.Routes.String(), "RouteBindingSelector", "RouteBindingSelector", 1), `&`, ``, 1) + `,`, `}`, }, "") return s @@ -6395,7 +6478,7 @@ func (m *GatewaySpec) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Routes", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Addresses", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -6422,7 +6505,8 @@ func (m *GatewaySpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Routes.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Addresses = append(m.Addresses, ListenerAddress{}) + if err := m.Addresses[len(m.Addresses)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -8211,7 +8295,7 @@ func (m *HTTPRouteStatus) Unmarshal(dAtA []byte) error { } return nil } -func (m *Listener) Unmarshal(dAtA []byte) error { +func (m *HostnameMatch) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -8234,15 +8318,15 @@ func (m *Listener) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Listener: wiretype end group for non-group") + return fmt.Errorf("proto: HostnameMatch: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Listener: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: HostnameMatch: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Match", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -8270,11 +8354,96 @@ func (m *Listener) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + m.Match = HostnameMatchType(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Listener) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Listener: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Listener: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hostname", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -8301,18 +8470,18 @@ func (m *Listener) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Address == nil { - m.Address = &ListenerAddress{} + if m.Hostname == nil { + m.Hostname = &HostnameMatch{} } - if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Hostname.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 3: + case 2: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) } - var v int32 + m.Port = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -8322,13 +8491,12 @@ func (m *Listener) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int32(b&0x7F) << shift + m.Port |= int32(b&0x7F) << shift if b < 0x80 { break } } - m.Port = &v - case 4: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) } @@ -8358,10 +8526,9 @@ func (m *Listener) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - s := string(dAtA[iNdEx:postIndex]) - m.Protocol = &s + m.Protocol = ProtocolType(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field TLS", wireType) } @@ -8397,9 +8564,9 @@ func (m *Listener) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 6: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExtensionRef", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Routes", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -8426,10 +8593,7 @@ func (m *Listener) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.ExtensionRef == nil { - m.ExtensionRef = &ConfigMapsDefaultLocalObjectReference{} - } - if err := m.ExtensionRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Routes.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/api/v1alpha1/generated.proto b/api/v1alpha1/generated.proto index ad0dbb44ce..c2e5bbc49b 100644 --- a/api/v1alpha1/generated.proto +++ b/api/v1alpha1/generated.proto @@ -95,7 +95,10 @@ message ForwardToTarget { optional int32 targetPort = 2; } -// Gateway represents an instantiation of a service-traffic handling infrastructure. +// Gateway represents an instantiation of a service-traffic handling +// infrastructure. The distinguishing characteristics of a gateway are +// that it has at least one IP address, and that it behaves as a network +// endpoint from the perspective of a client application. message Gateway { optional k8s.io.apimachinery.pkg.apis.meta.v1.TypeMeta typeMeta = 1; @@ -309,19 +312,27 @@ message GatewaySpec { // Class used for this Gateway. This is the name of a GatewayClass resource. optional string class = 1; - // Listeners associated with this Gateway. Listeners define what addresses, - // ports, protocols are bound on this Gateway. + // Listeners associated with this Gateway. Listeners define logical + // endpoints that are bound on this Gateway. If no Listeners are + // provided, the GatewayClass may associate the Gateway with + // an address but the Gateway will not be able to accept any + // connections. + // + // +optional repeated Listener listeners = 2; - // Routes specifies a schema for associating routes with the Gateway using - // selectors. A route is a resource capable of servicing a request and allows - // a cluster operator to expose a cluster resource (i.e. Service) by - // externally-reachable URL, load-balance traffic and terminate SSL/TLS. - // Typically, a route is a "httproute" or "tcproute" in group - // "networking.x-k8s.io". However, an implementation may support other resources. + // Address requested for this gateway. This is optional and behavior + // can depend on the GatewayClass. If a value is set in the spec and + // the requested address is invalid, the GatewayClass MUST indicate + // this in the associated entry in GatewayStatus.Listeners. If no + // addresses are specified, the GatewayClass may schedule the Gateway + // in an implementation-defined manner, providing it with an appropriate + // set of addresses. // - // Support: Core - optional RouteBindingSelector routes = 3; + // Support: + // + // +optional + repeated ListenerAddress endpoints = 3; } // GatewayStatus defines the observed state of Gateway. @@ -562,61 +573,128 @@ message HTTPRouteStatus { repeated GatewayObjectReference gatewayRefs = 1; } -// Listener defines a -message Listener { - // Name is the listener's name and should be specified as an - // RFC 1035 DNS_LABEL [1]: - // - // [1] https://tools.ietf.org/html/rfc1035 +// HostnameMatch specifies how a Listener should match the host name from a +// client request. Depending on the incoming protocol, the match may apply to +// the TLS and the HTTP protocol. +message HostnameMatch { + // Match specifies how the host name provided by the client should be + // matched against the given value. // - // Each listener of a Gateway must have a unique name. Name is used - // for associating a listener in Gateway status. + // +optional + // +kubebuilder:validation:Enum=Domain;Exact + // +kubebuilder:default=Exact + optional string match = 1; + + // Value contains the value to match against. This value must be a + // fully qualified host or domain name as defined by + // [RFC 3986](https://tools.ietf.org/html/rfc3986#section-3.2.2). + // Note the following deviations from the "host" part of the URI as defined in the RFC: // - // Support: Core + // 1. IPs are not allowed. + // 2. The `:` delimiter is not respected because ports are not allowed. // // +required - optional string name = 1; + // +kubebuilder:validation:MinLength=1 + optional string value = 2; +} - // Address requested for this listener. This is optional and behavior - // can depend on GatewayClass. If a value is set in the spec and - // the request address is invalid, the GatewayClass MUST indicate - // this in the associated entry in GatewayStatus.Listeners. +// Listener embodies the concept of a logical endpoint where a +// Gateway can accept network connections. +// +// The GatewayClass may collapse Listener definitions into single +// implementation-defined acceptor configuration. This allows Gateways to +// be implemented in terms of virtual services configured within the same +// proxy server process. +// +// Listeners may be considered collapsible if the Protocol field is +// "HTTP", "HTTPS" or "TLS", the Hostname field is specified, and the Port +// field matches. As a special case, each group of collapsed Listeners may +// contain up to one Listener that omits the Hostname field. Listeners that +// specify identical Hostname fields must not be treated as collapsible. +// +// If the GatewayClass collapses Listeners, the Hostname field must be matched +// in order of most to least specific. "Exact" matches must be processed before +// "Domain" matches, which must be processed before Listeners with no Hostname +// field. +// +// If the Gateway specifies multiple Listeners that have the same Port value +// but are not collapsible, the GatewayClass must raise a "PortConflict" +// condition on the Gateway. +message Listener { + // Hostname specifies the virtual host name for protocol types + // that define this concept. // - // Support: + // Incoming requests are matched against Hostname before processing + // HTTPRoute rules. For example, if the HTTP request header + // contains "Host: foo.example.com", an Listener with Hostname value + // "foo.example.com" will be an "Exact" match, but a Listener with + // Hostname values "example.com" or "bar.example.com" will not + // match. However these host names would match against a "Domain" + // match type with a value of "example.com". + // + // If Hostname is unspecified, the Gateway routes all traffic based on + // the specified rules. + // + // A Hostname match should be supplied for "HTTP" and "HTTPS" + // protocols, and may be supplied for "TLS" protocol. If no + // match is supplied, then this Listener must accept all client + // connections on the specified Port. + // + // As Listener that omits this field may be collapsed with other + // Listeners on the same port and protocol. There may be only + // one such Listener per Port. If more that one is configured, + // the GatewayClass must raise a "NameConflict" condition. + // + // Support: Core // // +optional - optional ListenerAddress address = 2; + optional HostnameMatch hostname = 1; - // Port is a list of ports associated with the Address. + // Port is the network port. Multiple listeners may use the + // same port, subject to the Listener collapsing rules. // - // Support: - // +optional - optional int32 port = 3; + // Support: Core + // + // +required + optional int32 port = 2; - // Protocol to use. + // Protocol specifies the application protocol this listener expects to receive. // - // Support: - // +optional - optional string protocol = 4; + // Support: Core + // + // +required + // +kubebuilder:validation:Enum=HTTP;HTTPS;TLS;TCP + optional string protocol = 3; // TLS is the TLS configuration for the Listener. If unspecified, - // the listener will not support TLS connections. + // the Listener will not support TLS connections. If the Hostname + // field is also specified, this endpoint must only accept TLS + // sessions where the client sends a TLS Server Name Indication (SNI) + // extension, and that value matches against the Listener's Hostname + // field. + // + // If the Protocol field is "HTTPS" or "TLS", this field is required. // // Support: Core // // +optional - optional TLSConfig tls = 5; + optional TLSConfig tls = 4; - // ExtensionRef for this Listener. The resource may be "configmaps" or - // an implementation-defined resource (for example, resource - // "mylisteners" in group "networking.acme.io"). Omitting or specifying - // the empty string for both the resource and group indicates that the - // resource is "configmaps". If the referent cannot be found, the - // listener's "InvalidListener" status condition will be true. + // Routes specifies a schema for associating routes with the Gateway using + // selectors. A route is a resource capable of servicing a request and allows + // a cluster operator to expose a cluster resource (i.e. Service) by + // externally-reachable URL, load-balance traffic and terminate SSL/TLS. + // Typically, a route is a "httproute" or "tcproute" in group + // "networking.x-k8s.io". However, an implementation may support other resources. // - // Support: custom. - // +optional - optional ConfigMapsDefaultLocalObjectReference extensionRef = 6; + // The Routes selector must select a set of objects that + // are compatible with the application protocol specified in + // the Protocol field. + // + // Support: Core + // + // +required + optional RouteBindingSelector routes = 5; } // ListenerAddress describes an address for the Listener. @@ -660,9 +738,13 @@ message ListenerCondition { // ListenerStatus is the status associated with each listener block. message ListenerStatus { // Name is the name of the listener this status refers to. + // TODO(jpeach) Listeners are not indexexd by a unique name any more, + // so this field probably doesn't make sense. optional string name = 1; // Address bound on this listener. + // TODO(jpeach) Listeners don't have addresses anymore so this field + // should move to the GatewayStatus. optional ListenerAddress address = 2; // Conditions describe the current condition of this listener. diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 7cabf593ab..3f01692311 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -283,7 +283,11 @@ func (in *GatewaySpec) DeepCopyInto(out *GatewaySpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - in.Routes.DeepCopyInto(&out.Routes) + if in.Addresses != nil { + in, out := &in.Addresses, &out.Addresses + *out = make([]ListenerAddress, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewaySpec. @@ -603,21 +607,26 @@ func (in *HTTPRouteStatus) DeepCopy() *HTTPRouteStatus { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Listener) DeepCopyInto(out *Listener) { +func (in *HostnameMatch) DeepCopyInto(out *HostnameMatch) { *out = *in - if in.Address != nil { - in, out := &in.Address, &out.Address - *out = new(ListenerAddress) - **out = **in - } - if in.Port != nil { - in, out := &in.Port, &out.Port - *out = new(int32) - **out = **in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostnameMatch. +func (in *HostnameMatch) DeepCopy() *HostnameMatch { + if in == nil { + return nil } - if in.Protocol != nil { - in, out := &in.Protocol, &out.Protocol - *out = new(string) + out := new(HostnameMatch) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Listener) DeepCopyInto(out *Listener) { + *out = *in + if in.Hostname != nil { + in, out := &in.Hostname, &out.Hostname + *out = new(HostnameMatch) **out = **in } if in.TLS != nil { @@ -625,11 +634,7 @@ func (in *Listener) DeepCopyInto(out *Listener) { *out = new(TLSConfig) (*in).DeepCopyInto(*out) } - if in.ExtensionRef != nil { - in, out := &in.ExtensionRef, &out.ExtensionRef - *out = new(ConfigMapsDefaultLocalObjectReference) - **out = **in - } + in.Routes.DeepCopyInto(&out.Routes) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Listener. diff --git a/config/crd/bases/networking.x-k8s.io_gateways.yaml b/config/crd/bases/networking.x-k8s.io_gateways.yaml index a8775390fd..1f349f7ad2 100644 --- a/config/crd/bases/networking.x-k8s.io_gateways.yaml +++ b/config/crd/bases/networking.x-k8s.io_gateways.yaml @@ -20,7 +20,9 @@ spec: schema: openAPIV3Schema: description: Gateway represents an instantiation of a service-traffic handling - infrastructure. + infrastructure. The distinguishing characteristics of a gateway are that + it has at least one IP address, and that it behaves as a network endpoint + from the perspective of a client application. properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation @@ -47,88 +49,240 @@ spec: description: Class used for this Gateway. This is the name of a GatewayClass resource. type: string + endpoints: + description: "Address requested for this gateway. This is optional + and behavior can depend on the GatewayClass. If a value is set in + the spec and the requested address is invalid, the GatewayClass + MUST indicate this in the associated entry in GatewayStatus.Listeners. + If no addresses are specified, the GatewayClass may schedule the + Gateway in an implementation-defined manner, providing it with an + appropriate set of addresses. \n Support:" + items: + description: ListenerAddress describes an address for the Listener. + properties: + type: + description: "Type of the Address. This is one of the *AddressType + constants. \n Support: Extended" + type: string + value: + description: 'Value. Examples: "1.2.3.4", "128::1", "my-ip-address". + Validity of the values will depend on `Type` and support by + the controller.' + type: string + required: + - type + - value + type: object + type: array listeners: description: Listeners associated with this Gateway. Listeners define - what addresses, ports, protocols are bound on this Gateway. + logical endpoints that are bound on this Gateway. If no Listeners + are provided, the GatewayClass may associate the Gateway with an + address but the Gateway will not be able to accept any connections. items: - description: Listener defines a + description: "Listener embodies the concept of a logical endpoint + where a Gateway can accept network connections. \n The GatewayClass + may collapse Listener definitions into single implementation-defined + acceptor configuration. This allows Gateways to be implemented + in terms of virtual services configured within the same proxy + server process. \n Listeners may be considered collapsible if + the Protocol field is \"HTTP\", \"HTTPS\" or \"TLS\", the Hostname + field is specified, and the Port field matches. As a special case, + each group of collapsed Listeners may contain up to one Listener + that omits the Hostname field. Listeners that specify identical + Hostname fields must not be treated as collapsible. \n If the + GatewayClass collapses Listeners, the Hostname field must be matched + in order of most to least specific. \"Exact\" matches must be + processed before \"Domain\" matches, which must be processed before + Listeners with no Hostname field. \n If the Gateway specifies + multiple Listeners that have the same Port value but are not collapsible, + the GatewayClass must raise a \"PortConflict\" condition on the + Gateway." properties: - address: - description: "Address requested for this listener. This is optional - and behavior can depend on GatewayClass. If a value is set - in the spec and the request address is invalid, the GatewayClass - MUST indicate this in the associated entry in GatewayStatus.Listeners. - \n Support:" + hostname: + description: "Hostname specifies the virtual host name for protocol + types that define this concept. \n Incoming requests are matched + against Hostname before processing HTTPRoute rules. For example, + if the HTTP request header contains \"Host: foo.example.com\", + an Listener with Hostname value \"foo.example.com\" will be + an \"Exact\" match, but a Listener with Hostname values \"example.com\" + or \"bar.example.com\" will not match. However these host + names would match against a \"Domain\" match type with a value + of \"example.com\". \n If Hostname is unspecified, the Gateway + routes all traffic based on the specified rules. \n A Hostname + match should be supplied for \"HTTP\" and \"HTTPS\" protocols, + and may be supplied for \"TLS\" protocol. If no match is supplied, + then this Listener must accept all client connections on the + specified Port. \n As Listener that omits this field may be + collapsed with other Listeners on the same port and protocol. + There may be only one such Listener per Port. If more that + one is configured, the GatewayClass must raise a \"NameConflict\" + condition. \n Support: Core" properties: - type: - description: "Type of the Address. This is one of the *AddressType - constants. \n Support: Extended" + match: + default: Exact + description: Match specifies how the host name provided + by the client should be matched against the given value. + enum: + - Domain + - Exact type: string value: - description: 'Value. Examples: "1.2.3.4", "128::1", "my-ip-address". - Validity of the values will depend on `Type` and support - by the controller.' + description: "Value contains the value to match against. + This value must be a fully qualified host or domain name + as defined by [RFC 3986](https://tools.ietf.org/html/rfc3986#section-3.2.2). + Note the following deviations from the \"host\" part of + the URI as defined in the RFC: \n 1. IPs are not allowed. + 2. The `:` delimiter is not respected because ports are + not allowed." + minLength: 1 type: string required: - - type - value type: object - extensionRef: - description: "ExtensionRef for this Listener. The resource - may be \"configmaps\" or an implementation-defined resource - (for example, resource \"mylisteners\" in group \"networking.acme.io\"). - \ Omitting or specifying the empty string for both the resource - and group indicates that the resource is \"configmaps\". If - the referent cannot be found, the listener's \"InvalidListener\" - status condition will be true. \n Support: custom." - properties: - group: - default: core - description: "Group is the group of the referent. Omitting - the value or specifying the empty string indicates the - core API group. For example, use the following to specify - a configmaps: \n fooRef: resource: configmaps name: - myconfigmap \n Otherwise, if the core API group is not - desired, specify the desired group: \n fooRef: group: - acme.io resource: foos name: myfoo" - type: string - name: - description: Name is the name of the referent. - type: string - resource: - default: configmaps - description: "Resource is the API resource name of the referent. - Omitting the value or specifying the empty string indicates - the configmaps resource. For example, use the following - to specify a configmaps resource: \n fooRef: name: myconfigmap - \n Otherwise, if the configmaps resource is not desired, - specify the desired group: \n fooRef: group: acme.io - \ resource: foos name: myfoo" - type: string - required: - - group - - name - - resource - type: object - name: - description: "Name is the listener's name and should be specified - as an RFC 1035 DNS_LABEL [1]: \n [1] https://tools.ietf.org/html/rfc1035 - \n Each listener of a Gateway must have a unique name. Name - is used for associating a listener in Gateway status. \n Support: - Core" - type: string port: - description: "Port is a list of ports associated with the Address. - \n Support:" + description: "Port is the network port. Multiple listeners may + use the same port, subject to the Listener collapsing rules. + \n Support: Core" format: int32 type: integer protocol: - description: "Protocol to use. \n Support:" + description: "Protocol specifies the application protocol this + listener expects to receive. \n Support: Core" + enum: + - HTTP + - HTTPS + - TLS + - TCP type: string + routes: + description: "Routes specifies a schema for associating routes + with the Gateway using selectors. A route is a resource capable + of servicing a request and allows a cluster operator to expose + a cluster resource (i.e. Service) by externally-reachable + URL, load-balance traffic and terminate SSL/TLS. Typically, + a route is a \"httproute\" or \"tcproute\" in group \"networking.x-k8s.io\". + However, an implementation may support other resources. \n + The Routes selector must select a set of objects that are + compatible with the application protocol specified in the + Protocol field. \n Support: Core" + properties: + namespaceSelector: + description: "NamespaceSelector specifies a set of namespace + labels used for selecting routes to associate with the + Gateway. If NamespaceSelector is defined, all routes in + namespaces matching the NamespaceSelector are associated + to the Gateway. \n An empty NamespaceSelector (default) + indicates that routes from any namespace will be associated + to this Gateway. This field is intentionally not a pointer + because the nil behavior (no namespaces) is undesirable + here. \n Support: Core" + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, + NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists + or DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field + is "key", the operator is "In", and the values array + contains only "value". The requirements are ANDed. + type: object + type: object + routeSelector: + description: "RouteSelector specifies a set of route labels + used for selecting routes to associate with the Gateway. + If RouteSelector is defined, only routes matching the + RouteSelector are associated with the Gateway. An empty + RouteSelector matches all routes. \n If undefined, route + labels are not used for associating routes to the gateway. + \n Support: Core" + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, + NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists + or DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field + is "key", the operator is "In", and the values array + contains only "value". The requirements are ANDed. + type: object + type: object + required: + - namespaceSelector + type: object tls: description: "TLS is the TLS configuration for the Listener. - If unspecified, the listener will not support TLS connections. - \n Support: Core" + If unspecified, the Listener will not support TLS connections. + If the Hostname field is also specified, this endpoint must + only accept TLS sessions where the client sends a TLS Server + Name Indication (SNI) extension, and that value matches against + the Listener's Hostname field. \n If the Protocol field is + \"HTTPS\" or \"TLS\", this field is required. \n Support: + Core" properties: certificateRefs: description: "CertificateRefs is a list of references to @@ -202,125 +356,11 @@ spec: - options type: object required: - - name + - routes type: object type: array - routes: - description: "Routes specifies a schema for associating routes with - the Gateway using selectors. A route is a resource capable of servicing - a request and allows a cluster operator to expose a cluster resource - (i.e. Service) by externally-reachable URL, load-balance traffic - and terminate SSL/TLS. Typically, a route is a \"httproute\" or - \"tcproute\" in group \"networking.x-k8s.io\". However, an implementation - may support other resources. \n Support: Core" - properties: - namespaceSelector: - description: "NamespaceSelector specifies a set of namespace labels - used for selecting routes to associate with the Gateway. If - NamespaceSelector is defined, all routes in namespaces matching - the NamespaceSelector are associated to the Gateway. \n An empty - NamespaceSelector (default) indicates that routes from any namespace - will be associated to this Gateway. This field is intentionally - not a pointer because the nil behavior (no namespaces) is undesirable - here. \n Support: Core" - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, - Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. If - the operator is In or NotIn, the values array must - be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A - single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field is "key", - the operator is "In", and the values array contains only - "value". The requirements are ANDed. - type: object - type: object - routeSelector: - description: "RouteSelector specifies a set of route labels used - for selecting routes to associate with the Gateway. If RouteSelector - is defined, only routes matching the RouteSelector are associated - with the Gateway. An empty RouteSelector matches all routes. - \n If undefined, route labels are not used for associating routes - to the gateway. \n Support: Core" - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, - Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. If - the operator is In or NotIn, the values array must - be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A - single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field is "key", - the operator is "In", and the values array contains only - "value". The requirements are ANDed. - type: object - type: object - required: - - namespaceSelector - type: object required: - class - - listeners - - routes type: object status: description: GatewayStatus defines the observed state of Gateway. @@ -364,7 +404,9 @@ spec: block. properties: address: - description: Address bound on this listener. + description: Address bound on this listener. TODO(jpeach) Listeners + don't have addresses anymore so this field should move to + the GatewayStatus. properties: type: description: "Type of the Address. This is one of the *AddressType @@ -413,7 +455,8 @@ spec: type: array name: description: Name is the name of the listener this status refers - to. + to. TODO(jpeach) Listeners are not indexexd by a unique name + any more, so this field probably doesn't make sense. type: string required: - address diff --git a/examples/multiple-https.yaml b/examples/multiple-https.yaml new file mode 100644 index 0000000000..85ba924c83 --- /dev/null +++ b/examples/multiple-https.yaml @@ -0,0 +1,37 @@ +kind: Gateway +apiVersion: networking.x-k8s.io/v1alpha1 +metadata: + name: gateway + namespace: default +spec: + class: default-class + addresses: + - type: NamedAddress + value: auto-assign + listeners: + - hostname: + value: httpbin.example.com + port: 443 + protocol: HTTPS + tls: + certificateRefs: + - resource: secrets + name: httpbin + routes: + - routeSelector: + matchLabels: + app: httpbin + - hostname: + value: conformance.example.com + port: 443 + protocol: HTTPS + tls: + certificateRefs: + - resource: secrets + name: conformance + routes: + - routeSelector: + matchLabels: + app: conformance + + diff --git a/examples/multiple-tcp.yaml b/examples/multiple-tcp.yaml new file mode 100644 index 0000000000..0cbeaa602a --- /dev/null +++ b/examples/multiple-tcp.yaml @@ -0,0 +1,40 @@ +kind: Gateway +apiVersion: networking.x-k8s.io/v1alpha1 +metadata: + name: gateway + namespace: ssh-server +spec: + class: default-class + addresses: + - type: NamedAddress + value: auto-assign + listeners: + # Forward port 22 to a SSH honeypot app. + - port: 22 + protocol: TCP + routes: + - routeSelector: + matchLabels: + app: sshd-honeypot + # Forward port 2222 to a real SSH server. + - port: 2222 + protocol: TCP + routes: + - routeSelector: + matchLabels: + app: sshd-legitimate + # Forward the SNI named service to the real SSH server ever TLS, assuming + # that there is an actual client for such a beast. + - hostname: + match: Exact + value: ssh.example.com + port: 443 + protocol: TLS + tls: + certificateRefs: + - resource: secrets + name: ssh-server + routes: + - routeSelector: + matchLabels: + app: sshd-legitimate diff --git a/examples/single-http.yaml b/examples/single-http.yaml new file mode 100644 index 0000000000..776c6aa4d2 --- /dev/null +++ b/examples/single-http.yaml @@ -0,0 +1,20 @@ +kind: Gateway +apiVersion: networking.x-k8s.io/v1alpha1 +metadata: + name: gateway + namespace: default +spec: + class: default-class + addresses: + - type: NamedAddress + value: auto-assign + listeners: + - hostname: + value: httpbin.example.com + port: 80 + protocol: HTTP + routes: + - routeSelector: + matchLabels: + app: httpbin + diff --git a/examples/wildcard-http.yaml b/examples/wildcard-http.yaml new file mode 100644 index 0000000000..95eb36ca95 --- /dev/null +++ b/examples/wildcard-http.yaml @@ -0,0 +1,25 @@ +kind: Gateway +apiVersion: networking.x-k8s.io/v1alpha1 +metadata: + name: gateway + namespace: default +spec: + class: default-class + addresses: + - type: NamedAddress + value: auto-assign + listeners: + - hostname: + match: Domain + value: example.com + port: 80 + protocol: HTTP + routes: + - routeSelector: + matchLabels: + app: httpbin + - routeSelector: + matchLabels: + app: conformance + + diff --git a/examples/wildcard-https.yaml b/examples/wildcard-https.yaml new file mode 100644 index 0000000000..8348fc5040 --- /dev/null +++ b/examples/wildcard-https.yaml @@ -0,0 +1,27 @@ +kind: Gateway +apiVersion: networking.x-k8s.io/v1alpha1 +metadata: + name: gateway + namespace: default +spec: + class: default-class + addresses: + - type: NamedAddress + value: auto-assign + listeners: + - hostname: + match: Domain + value: example.com + port: 443 + protocol: HTTPS + tls: + certificateRefs: + - resource: secrets + name: example-wildcard + routes: + - routeSelector: + matchLabels: + app: httpbin + - routeSelector: + matchLabels: + app: conformance