| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* |
| * |
| * Copyright 2021 gRPC authors. |
| * |
| */ |
| |
| package resource |
| |
| import ( |
| "regexp" |
| "time" |
| ) |
| |
| import ( |
| "google.golang.org/grpc/codes" |
| |
| "google.golang.org/protobuf/types/known/anypb" |
| ) |
| |
| import ( |
| "dubbo.apache.org/dubbo-go/v3/xds/clusterspecifier" |
| "dubbo.apache.org/dubbo-go/v3/xds/httpfilter" |
| "dubbo.apache.org/dubbo-go/v3/xds/utils/matcher" |
| ) |
| |
| // RouteConfigUpdate contains information received in an RDS response, which is |
| // of interest to the registered RDS watcher. |
| type RouteConfigUpdate struct { |
| VirtualHosts []*VirtualHost |
| // ClusterSpecifierPlugins are the LB Configurations for any |
| // ClusterSpecifierPlugins referenced by the Route Table. |
| ClusterSpecifierPlugins map[string]clusterspecifier.BalancerConfig |
| // Raw is the resource from the xds response. |
| Raw *anypb.Any |
| } |
| |
| // VirtualHost contains the routes for a list of Domains. |
| // |
| // Note that the domains in this slice can be a wildcard, not an exact string. |
| // The consumer of this struct needs to find the best match for its hostname. |
| type VirtualHost struct { |
| Domains []string |
| // Routes contains a list of routes, each containing matchers and |
| // corresponding action. |
| Routes []*Route |
| // HTTPFilterConfigOverride contains any HTTP filter config overrides for |
| // the virtual host which may be present. An individual filter's override |
| // may be unused if the matching Route contains an override for that |
| // filter. |
| HTTPFilterConfigOverride map[string]httpfilter.FilterConfig |
| RetryConfig *RetryConfig |
| } |
| |
| // RetryConfig contains all retry-related configuration in either a VirtualHost |
| // or Route. |
| type RetryConfig struct { |
| // RetryOn is a set of status codes on which to retry. Only Canceled, |
| // DeadlineExceeded, Internal, ResourceExhausted, and Unavailable are |
| // supported; any other values will be omitted. |
| RetryOn map[codes.Code]bool |
| NumRetries uint32 // maximum number of retry attempts |
| RetryBackoff RetryBackoff // retry backoff policy |
| } |
| |
| // RetryBackoff describes the backoff policy for retries. |
| type RetryBackoff struct { |
| BaseInterval time.Duration // initial backoff duration between attempts |
| MaxInterval time.Duration // maximum backoff duration |
| } |
| |
| // HashPolicyType specifies the type of HashPolicy from a received RDS Response. |
| type HashPolicyType int |
| |
| const ( |
| // HashPolicyTypeHeader specifies to hash a Header in the incoming request. |
| HashPolicyTypeHeader HashPolicyType = iota |
| // HashPolicyTypeChannelID specifies to hash a unique Identifier of the |
| // Channel. In grpc-go, this will be done using the ClientConn pointer. |
| HashPolicyTypeChannelID |
| ) |
| |
| // HashPolicy specifies the HashPolicy if the upstream cluster uses a hashing |
| // load balancer. |
| type HashPolicy struct { |
| HashPolicyType HashPolicyType |
| Terminal bool |
| // Fields used for type HEADER. |
| HeaderName string |
| Regex *regexp.Regexp |
| RegexSubstitution string |
| } |
| |
| // RouteActionType is the action of the route from a received RDS response. |
| type RouteActionType int |
| |
| const ( |
| // RouteActionUnsupported are routing types currently unsupported by grpc. |
| // According to A36, "A Route with an inappropriate action causes RPCs |
| // matching that route to fail." |
| RouteActionUnsupported RouteActionType = iota |
| // RouteActionRoute is the expected route type on the client side. Route |
| // represents routing a request to some upstream cluster. On the client |
| // side, if an RPC matches to a route that is not RouteActionRoute, the RPC |
| // will fail according to A36. |
| RouteActionRoute |
| // RouteActionNonForwardingAction is the expected route type on the server |
| // side. NonForwardingAction represents when a route will generate a |
| // response directly, without forwarding to an upstream host. |
| RouteActionNonForwardingAction |
| ) |
| |
| // Route is both a specification of how to match a request as well as an |
| // indication of the action to take upon match. |
| type Route struct { |
| Path *string |
| Prefix *string |
| Regex *regexp.Regexp |
| // Indicates if prefix/path matching should be case insensitive. The default |
| // is false (case sensitive). |
| CaseInsensitive bool |
| Headers []*HeaderMatcher |
| Fraction *uint32 |
| |
| HashPolicies []*HashPolicy |
| |
| // If the matchers above indicate a match, the below configuration is used. |
| // If MaxStreamDuration is nil, it indicates neither of the route action's |
| // max_stream_duration fields (grpc_timeout_header_max nor |
| // max_stream_duration) were set. In this case, the ListenerUpdate's |
| // MaxStreamDuration field should be used. If MaxStreamDuration is set to |
| // an explicit zero duration, the application's deadline should be used. |
| MaxStreamDuration *time.Duration |
| // HTTPFilterConfigOverride contains any HTTP filter config overrides for |
| // the route which may be present. An individual filter's override may be |
| // unused if the matching WeightedCluster contains an override for that |
| // filter. |
| HTTPFilterConfigOverride map[string]httpfilter.FilterConfig |
| RetryConfig *RetryConfig |
| |
| ActionType RouteActionType |
| |
| // Only one of the following fields (WeightedClusters or |
| // ClusterSpecifierPlugin) will be set for a route. |
| WeightedClusters map[string]WeightedCluster |
| // ClusterSpecifierPlugin is the name of the Cluster Specifier Plugin that |
| // this Route is linked to, if specified by xDS. |
| ClusterSpecifierPlugin string |
| } |
| |
| // WeightedCluster contains settings for an xds ActionType.WeightedCluster. |
| type WeightedCluster struct { |
| // Weight is the relative weight of the cluster. It will never be zero. |
| Weight uint32 |
| // HTTPFilterConfigOverride contains any HTTP filter config overrides for |
| // the weighted cluster which may be present. |
| HTTPFilterConfigOverride map[string]httpfilter.FilterConfig |
| } |
| |
| // HeaderMatcher represents header matchers. |
| type HeaderMatcher struct { |
| Name string |
| InvertMatch *bool |
| ExactMatch *string |
| RegexMatch *regexp.Regexp |
| PrefixMatch *string |
| SuffixMatch *string |
| RangeMatch *Int64Range |
| PresentMatch *bool |
| } |
| |
| // Int64Range is a range for header range match. |
| type Int64Range struct { |
| Start int64 |
| End int64 |
| } |
| |
| // SecurityConfig contains the security configuration received as part of the |
| // Cluster resource on the client-side, and as part of the Listener resource on |
| // the server-side. |
| type SecurityConfig struct { |
| // RootInstanceName identifies the certProvider plugin to be used to fetch |
| // root certificates. This instance name will be resolved to the plugin name |
| // and its associated configuration from the certificate_providers field of |
| // the bootstrap file. |
| RootInstanceName string |
| // RootCertName is the certificate name to be passed to the plugin (looked |
| // up from the bootstrap file) while fetching root certificates. |
| RootCertName string |
| // IdentityInstanceName identifies the certProvider plugin to be used to |
| // fetch identity certificates. This instance name will be resolved to the |
| // plugin name and its associated configuration from the |
| // certificate_providers field of the bootstrap file. |
| IdentityInstanceName string |
| // IdentityCertName is the certificate name to be passed to the plugin |
| // (looked up from the bootstrap file) while fetching identity certificates. |
| IdentityCertName string |
| // SubjectAltNameMatchers is an optional list of match criteria for SANs |
| // specified on the peer certificate. Used only on the client-side. |
| // |
| // Some intricacies: |
| // - If this field is empty, then any peer certificate is accepted. |
| // - If the peer certificate contains a wildcard DNS SAN, and an `exact` |
| // matcher is configured, a wildcard DNS match is performed instead of a |
| // regular string comparison. |
| SubjectAltNameMatchers []matcher.StringMatcher |
| // RequireClientCert indicates if the server handshake process expects the |
| // client to present a certificate. Set to true when performing mTLS. Used |
| // only on the server-side. |
| RequireClientCert bool |
| } |
| |
| // Equal returns true if sc is equal to other. |
| func (sc *SecurityConfig) Equal(other *SecurityConfig) bool { |
| switch { |
| case sc == nil && other == nil: |
| return true |
| case (sc != nil) != (other != nil): |
| return false |
| } |
| switch { |
| case sc.RootInstanceName != other.RootInstanceName: |
| return false |
| case sc.RootCertName != other.RootCertName: |
| return false |
| case sc.IdentityInstanceName != other.IdentityInstanceName: |
| return false |
| case sc.IdentityCertName != other.IdentityCertName: |
| return false |
| case sc.RequireClientCert != other.RequireClientCert: |
| return false |
| default: |
| if len(sc.SubjectAltNameMatchers) != len(other.SubjectAltNameMatchers) { |
| return false |
| } |
| for i := 0; i < len(sc.SubjectAltNameMatchers); i++ { |
| if !sc.SubjectAltNameMatchers[i].Equal(other.SubjectAltNameMatchers[i]) { |
| return false |
| } |
| } |
| } |
| return true |
| } |
| |
| // RouteConfigUpdateErrTuple is a tuple with the update and error. It contains |
| // the results from unmarshal functions. It's used to pass unmarshal results of |
| // multiple resources together, e.g. in maps like `map[string]{Update,error}`. |
| type RouteConfigUpdateErrTuple struct { |
| Update RouteConfigUpdate |
| Err error |
| } |