Compare commits
2 Commits
Author | SHA1 | Date |
---|---|---|
longXboy | b7379f0c6e | 3 years ago |
longXboy | 9b34658a5c | 3 years ago |
@ -0,0 +1,214 @@ |
||||
/* |
||||
* |
||||
* Copyright 2020 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
// Package v3 provides xDS v3 transport protocol specific functionality.
|
||||
package v3 |
||||
|
||||
import ( |
||||
"context" |
||||
"fmt" |
||||
"sync" |
||||
|
||||
"github.com/go-kratos/kratos/v2/errors" |
||||
"github.com/go-kratos/kratos/v2/log" |
||||
"github.com/go-kratos/kratos/v2/xds/resource" |
||||
|
||||
v3corepb "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" |
||||
v3adsgrpc "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" |
||||
v3discoverypb "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" |
||||
statuspb "google.golang.org/genproto/googleapis/rpc/status" |
||||
"google.golang.org/grpc" |
||||
"google.golang.org/grpc/codes" |
||||
"google.golang.org/protobuf/proto" |
||||
) |
||||
|
||||
const ( |
||||
reasonSendError = "send_error" |
||||
) |
||||
|
||||
// BuildOptions contains options to be passed to client builders.
|
||||
type BuildOptions struct { |
||||
// NodeProto contains the Node proto to be used in xDS requests. The actual
|
||||
// type depends on the transport protocol version used.
|
||||
NodeProto proto.Message |
||||
// // Backoff returns the amount of time to backoff before retrying broken
|
||||
// // streams.
|
||||
// Backoff func(int) time.Duration
|
||||
// Logger provides enhanced logging capabilities.
|
||||
Logger *log.Helper |
||||
} |
||||
|
||||
var ( |
||||
resourceTypeToURL = map[resource.ResourceType]string{ |
||||
resource.ListenerResource: resource.V3ListenerURL, |
||||
resource.RouteConfigResource: resource.V3RouteConfigURL, |
||||
resource.ClusterResource: resource.V3ClusterURL, |
||||
resource.EndpointsResource: resource.V3EndpointsURL, |
||||
} |
||||
) |
||||
|
||||
// NewClient new xds client
|
||||
func NewClient(cc *grpc.ClientConn, opts BuildOptions) (*Client, error) { |
||||
nodeProto, ok := opts.NodeProto.(*v3corepb.Node) |
||||
if !ok { |
||||
return nil, fmt.Errorf("xds: unsupported Node proto type: %T, want %T", opts.NodeProto, v3corepb.Node{}) |
||||
} |
||||
c := &Client{ |
||||
nodeProto: nodeProto, |
||||
logger: opts.Logger, |
||||
watchMp: make(map[resource.ResourceType]map[string]bool), |
||||
versionMp: make(map[resource.ResourceType]string), |
||||
nonceMp: make(map[resource.ResourceType]string), |
||||
cc: cc, |
||||
} |
||||
c.ctx, c.cancel = context.WithCancel(context.Background()) |
||||
return c, nil |
||||
} |
||||
|
||||
type adsStream v3adsgrpc.AggregatedDiscoveryService_StreamAggregatedResourcesClient |
||||
|
||||
// client performs the actual xDS RPCs using the xDS v3 API. It creates a
|
||||
// single ADS stream on which the different types of xDS requests and responses
|
||||
// are multiplexed.
|
||||
type Client struct { |
||||
nodeProto *v3corepb.Node |
||||
logger *log.Helper |
||||
cc *grpc.ClientConn // Connection to the management server.
|
||||
|
||||
watchMp map[resource.ResourceType]map[string]bool |
||||
versionMp map[resource.ResourceType]string |
||||
nonceMp map[resource.ResourceType]string |
||||
ackCh chan *ackAction |
||||
watchCh chan *watchAction |
||||
ctx context.Context |
||||
cancel context.CancelFunc |
||||
lk sync.RWMutex |
||||
stream adsStream |
||||
} |
||||
|
||||
func (c *Client) newStream(ctx context.Context, cc *grpc.ClientConn) (adsStream, error) { |
||||
return v3adsgrpc.NewAggregatedDiscoveryServiceClient(cc).StreamAggregatedResources(ctx, grpc.WaitForReady(true)) |
||||
} |
||||
|
||||
func (c *Client) SendAck(stream adsStream, rType resource.ResourceType, version, nonce, errMsg string) error { |
||||
c.lk.Lock() |
||||
c.nonceMp[rType] = nonce |
||||
s, ok := c.watchMp[rType] |
||||
if !ok || len(s) == 0 { |
||||
c.lk.Unlock() |
||||
// We don't send the request ack if there's no active watch (this can be
|
||||
// either the server sends responses before any request, or the watch is
|
||||
// canceled while the ackAction is in queue), because there's no resource
|
||||
// name. And if we send a request with empty resource name list, the
|
||||
// server may treat it as a wild card and send us everything.
|
||||
return errors.NotFound(resource.UnknownResource.String(), rType.String()) |
||||
} |
||||
target := mapToSlice(s) |
||||
if version == "" { |
||||
// This is a nack, get the previous acked version.
|
||||
version = c.versionMp[rType] |
||||
// version will still be an empty string if rType isn't
|
||||
// found in versionMap, this can happen if there wasn't any ack
|
||||
// before.
|
||||
} else { |
||||
c.versionMp[rType] = version |
||||
} |
||||
c.lk.Unlock() |
||||
|
||||
return c.sendRequest(stream, target, rType, version, nonce, errMsg) |
||||
} |
||||
|
||||
func (c *Client) WatchResource(s adsStream, rType resource.ResourceType, resource string, remove bool) error { |
||||
c.lk.Lock() |
||||
|
||||
var current map[string]bool |
||||
current, ok := c.watchMp[rType] |
||||
if !ok { |
||||
current = make(map[string]bool) |
||||
c.watchMp[rType] = current |
||||
} |
||||
if remove { |
||||
delete(current, resource) |
||||
if len(current) == 0 { |
||||
delete(c.watchMp, rType) |
||||
} |
||||
} else { |
||||
current[resource] = true |
||||
} |
||||
target := mapToSlice(current) |
||||
// We don't reset version or nonce when a new watch is started. The version
|
||||
// and nonce from previous response are carried by the request unless the
|
||||
// stream is recreated.
|
||||
ver := c.versionMp[rType] |
||||
nonce := c.nonceMp[rType] |
||||
c.lk.Unlock() |
||||
return c.sendRequest(s, target, rType, ver, nonce, "") |
||||
} |
||||
|
||||
// sendRequest sends out a DiscoveryRequest for the given resourceNames, of type
|
||||
// rType, on the provided stream.
|
||||
//
|
||||
// version is the ack version to be sent with the request
|
||||
// - If this is the new request (not an ack/nack), version will be empty.
|
||||
// - If this is an ack, version will be the version from the response.
|
||||
// - If this is a nack, version will be the previous acked version (from
|
||||
// versionMap). If there was no ack before, it will be empty.
|
||||
func (c *Client) sendRequest(stream adsStream, resourceNames []string, rType resource.ResourceType, version, nonce, errMsg string) error { |
||||
req := &v3discoverypb.DiscoveryRequest{ |
||||
Node: c.nodeProto, |
||||
TypeUrl: resourceTypeToURL[rType], |
||||
ResourceNames: resourceNames, |
||||
VersionInfo: version, |
||||
ResponseNonce: nonce, |
||||
} |
||||
if errMsg != "" { |
||||
req.ErrorDetail = &statuspb.Status{ |
||||
Code: int32(codes.InvalidArgument), Message: errMsg, |
||||
} |
||||
} |
||||
if err := stream.Send(req); err != nil { |
||||
return errors.ServiceUnavailable(reasonSendError, fmt.Sprintf("xds: stream.Send(%+v) failed: %v", req, err)) |
||||
} |
||||
c.logger.Debugf("ADS request sent: %v", (req)) |
||||
return nil |
||||
} |
||||
|
||||
// RecvResponse blocks on the receipt of one response message on the provided
|
||||
// stream.
|
||||
func (c *Client) RecvResponse(stream adsStream) (proto.Message, error) { |
||||
resp, err := stream.Recv() |
||||
if err != nil { |
||||
return nil, fmt.Errorf("xds: stream.Recv() failed: %v", err) |
||||
} |
||||
c.logger.Infof("ADS response received, type: %v", resp.GetTypeUrl()) |
||||
c.logger.Debugf("ADS response received: %+v", (resp)) |
||||
return resp, nil |
||||
} |
||||
|
||||
func mapToSlice(m map[string]bool) []string { |
||||
ret := make([]string, 0, len(m)) |
||||
for i := range m { |
||||
ret = append(ret, i) |
||||
} |
||||
return ret |
||||
} |
||||
|
||||
func (c *Client) Close() error { |
||||
c.cancel() |
||||
return c.cc.Close() |
||||
} |
@ -0,0 +1,214 @@ |
||||
package v3 |
||||
|
||||
import ( |
||||
"time" |
||||
|
||||
v3clusterpb "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" |
||||
v3endpointpb "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3" |
||||
v3listenerpb "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" |
||||
v3routepb "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" |
||||
v3discoverypb "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" |
||||
"github.com/go-kratos/kratos/v2/errors" |
||||
"github.com/go-kratos/kratos/v2/xds/resource" |
||||
"google.golang.org/grpc" |
||||
"google.golang.org/protobuf/proto" |
||||
) |
||||
|
||||
func (c *Client) run() { |
||||
go c.sendLoop() |
||||
|
||||
for { |
||||
select { |
||||
case <-c.ctx.Done(): |
||||
return |
||||
default: |
||||
} |
||||
stream, err := c.getStream() |
||||
if err != nil { |
||||
time.Sleep(time.Second * 3) |
||||
continue |
||||
} |
||||
c.recv(stream) |
||||
} |
||||
} |
||||
|
||||
func (c *Client) recv(stream adsStream) error { |
||||
|
||||
for { |
||||
r, err := c.RecvResponse(stream) |
||||
if err != nil { |
||||
c.resetStream(c.stream) |
||||
return err |
||||
} |
||||
rType := resource.UnknownResource |
||||
resp, ok := r.(*v3discoverypb.DiscoveryResponse) |
||||
if !ok { |
||||
// send nack
|
||||
c.ackCh <- &ackAction{ |
||||
rType: rType, |
||||
version: "", |
||||
nonce: resp.Nonce, |
||||
errMsg: err.Error(), |
||||
stream: stream, |
||||
} |
||||
continue |
||||
} |
||||
|
||||
// Note that the xDS transport protocol is versioned independently of
|
||||
// the resource types, and it is supported to transfer older versions
|
||||
// of resource types using new versions of the transport protocol, or
|
||||
// vice-versa. Hence we need to handle v3 type_urls as well here.
|
||||
url := resp.GetTypeUrl() |
||||
switch { |
||||
case resource.IsListenerResource(url): |
||||
rType = resource.ListenerResource |
||||
for _, res := range resp.GetResources() { |
||||
lis := &v3listenerpb.Listener{} |
||||
err = proto.Unmarshal(res.GetValue(), lis) |
||||
if err != nil { |
||||
break |
||||
} |
||||
} |
||||
case resource.IsRouteConfigResource(url): |
||||
rType = resource.RouteConfigResource |
||||
for _, res := range resp.GetResources() { |
||||
rc := &v3routepb.RouteConfiguration{} |
||||
err = proto.Unmarshal(res.GetValue(), rc) |
||||
if err != nil { |
||||
break |
||||
} |
||||
} |
||||
case resource.IsClusterResource(url): |
||||
rType = resource.ClusterResource |
||||
for _, res := range resp.GetResources() { |
||||
cluster := &v3clusterpb.Cluster{} |
||||
err = proto.Unmarshal(res.GetValue(), cluster) |
||||
if err != nil { |
||||
break |
||||
} |
||||
} |
||||
case resource.IsEndpointsResource(url): |
||||
rType = resource.EndpointsResource |
||||
for _, res := range resp.GetResources() { |
||||
cla := &v3endpointpb.ClusterLoadAssignment{} |
||||
err = proto.Unmarshal(res.GetValue(), cla) |
||||
if err != nil { |
||||
break |
||||
} |
||||
} |
||||
default: |
||||
// Unknown resource type
|
||||
continue |
||||
} |
||||
if err != nil { |
||||
// send nack
|
||||
// send nack
|
||||
c.ackCh <- &ackAction{ |
||||
rType: rType, |
||||
version: "", |
||||
nonce: resp.Nonce, |
||||
errMsg: err.Error(), |
||||
stream: stream, |
||||
} |
||||
} else { |
||||
c.ackCh <- &ackAction{ |
||||
rType: rType, |
||||
version: resp.GetVersionInfo(), |
||||
nonce: resp.GetNonce(), |
||||
stream: stream, |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
func (c *Client) sendLoop() { |
||||
for { |
||||
select { |
||||
case <-c.ctx.Done(): |
||||
return |
||||
case action := <-c.watchCh: |
||||
stream, err := c.getStream() |
||||
if err != nil { |
||||
c.logger.Errorf("xds client get stream failed!err:=%v", err) |
||||
continue |
||||
} |
||||
err = c.WatchResource(stream, action.rType, action.resource, action.remove) |
||||
if err != nil { |
||||
c.logger.Errorf("xds client watch resource failed!err:=%v", err) |
||||
if errors.IsServiceUnavailable(err) { |
||||
c.resetStream(stream) |
||||
} |
||||
} |
||||
case action := <-c.ackCh: |
||||
stream, err := c.getStream() |
||||
if err != nil { |
||||
c.logger.Errorf("xds client get stream failed!err:=%v", err) |
||||
continue |
||||
} |
||||
if action.stream != stream { |
||||
continue |
||||
} |
||||
err = c.SendAck(stream, action.rType, action.version, action.nonce, action.errMsg) |
||||
if err != nil { |
||||
c.logger.Errorf("xds client send ack failed!err:=%v", err) |
||||
if errors.IsServiceUnavailable(err) { |
||||
c.resetStream(stream) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
func (c *Client) resetStream(origin adsStream) { |
||||
c.lk.Lock() |
||||
if origin == c.stream { |
||||
c.stream = nil |
||||
} |
||||
c.lk.Unlock() |
||||
} |
||||
|
||||
func (c *Client) getStream() (adsStream, error) { |
||||
c.lk.RLock() |
||||
if c.stream == nil { |
||||
c.lk.RUnlock() |
||||
|
||||
c.lk.Lock() |
||||
defer c.lk.Unlock() |
||||
if c.stream == nil { |
||||
var err error |
||||
for i := 0; i < 3; i++ { |
||||
c.stream, err = c.newStream(c.ctx, c.cc) |
||||
if err == nil { |
||||
return c.stream, nil |
||||
} |
||||
if i < 2 { |
||||
time.Sleep(time.Millisecond * 250 * time.Duration(i+1)) |
||||
} |
||||
} |
||||
return nil, err |
||||
} |
||||
return c.stream, nil |
||||
} |
||||
defer c.lk.RUnlock() |
||||
return c.stream, nil |
||||
|
||||
} |
||||
|
||||
type watchAction struct { |
||||
rType resource.ResourceType |
||||
remove bool // Whether this is to remove watch for the resource.
|
||||
resource string |
||||
} |
||||
|
||||
type ackAction struct { |
||||
rType resource.ResourceType |
||||
version string // NACK if version is an empty string.
|
||||
nonce string |
||||
errMsg string // Empty unless it's a NACK.
|
||||
// ACK/NACK are tagged with the stream it's for. When the stream is down,
|
||||
// all the ACK/NACK for this stream will be dropped, and the version/nonce
|
||||
// won't be updated.
|
||||
stream grpc.ClientStream |
||||
} |
@ -0,0 +1,149 @@ |
||||
/* |
||||
* |
||||
* Copyright 2021 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package resource |
||||
|
||||
import ( |
||||
"time" |
||||
|
||||
"google.golang.org/protobuf/types/known/anypb" |
||||
) |
||||
|
||||
// UpdateValidatorFunc performs validations on update structs using
|
||||
// context/logic available at the xdsClient layer. Since these validation are
|
||||
// performed on internal update structs, they can be shared between different
|
||||
// API clients.
|
||||
type UpdateValidatorFunc func(interface{}) error |
||||
|
||||
// UpdateMetadata contains the metadata for each update, including timestamp,
|
||||
// raw message, and so on.
|
||||
type UpdateMetadata struct { |
||||
// Status is the status of this resource, e.g. ACKed, NACKed, or
|
||||
// Not_exist(removed).
|
||||
Status ServiceStatus |
||||
// Version is the version of the xds response. Note that this is the version
|
||||
// of the resource in use (previous ACKed). If a response is NACKed, the
|
||||
// NACKed version is in ErrState.
|
||||
Version string |
||||
// Timestamp is when the response is received.
|
||||
Timestamp time.Time |
||||
// ErrState is set when the update is NACKed.
|
||||
ErrState *UpdateErrorMetadata |
||||
} |
||||
|
||||
// IsListenerResource returns true if the provider URL corresponds to an xDS
|
||||
// Listener resource.
|
||||
func IsListenerResource(url string) bool { |
||||
return url == V2ListenerURL || url == V3ListenerURL |
||||
} |
||||
|
||||
// IsHTTPConnManagerResource returns true if the provider URL corresponds to an xDS
|
||||
// HTTPConnManager resource.
|
||||
func IsHTTPConnManagerResource(url string) bool { |
||||
return url == V2HTTPConnManagerURL || url == V3HTTPConnManagerURL |
||||
} |
||||
|
||||
// IsRouteConfigResource returns true if the provider URL corresponds to an xDS
|
||||
// RouteConfig resource.
|
||||
func IsRouteConfigResource(url string) bool { |
||||
return url == V2RouteConfigURL || url == V3RouteConfigURL |
||||
} |
||||
|
||||
// IsClusterResource returns true if the provider URL corresponds to an xDS
|
||||
// Cluster resource.
|
||||
func IsClusterResource(url string) bool { |
||||
return url == V2ClusterURL || url == V3ClusterURL |
||||
} |
||||
|
||||
// IsEndpointsResource returns true if the provider URL corresponds to an xDS
|
||||
// Endpoints resource.
|
||||
func IsEndpointsResource(url string) bool { |
||||
return url == V2EndpointsURL || url == V3EndpointsURL |
||||
} |
||||
|
||||
// ServiceStatus is the status of the update.
|
||||
type ServiceStatus int |
||||
|
||||
const ( |
||||
// ServiceStatusUnknown is the default state, before a watch is started for
|
||||
// the resource.
|
||||
ServiceStatusUnknown ServiceStatus = iota |
||||
// ServiceStatusRequested is when the watch is started, but before and
|
||||
// response is received.
|
||||
ServiceStatusRequested |
||||
// ServiceStatusNotExist is when the resource doesn't exist in
|
||||
// state-of-the-world responses (e.g. LDS and CDS), which means the resource
|
||||
// is removed by the management server.
|
||||
ServiceStatusNotExist // Resource is removed in the server, in LDS/CDS.
|
||||
// ServiceStatusACKed is when the resource is ACKed.
|
||||
ServiceStatusACKed |
||||
// ServiceStatusNACKed is when the resource is NACKed.
|
||||
ServiceStatusNACKed |
||||
) |
||||
|
||||
// UpdateErrorMetadata is part of UpdateMetadata. It contains the error state
|
||||
// when a response is NACKed.
|
||||
type UpdateErrorMetadata struct { |
||||
// Version is the version of the NACKed response.
|
||||
Version string |
||||
// Err contains why the response was NACKed.
|
||||
Err error |
||||
// Timestamp is when the NACKed response was received.
|
||||
Timestamp time.Time |
||||
} |
||||
|
||||
// UpdateWithMD contains the raw message of the update and the metadata,
|
||||
// including version, raw message, timestamp.
|
||||
//
|
||||
// This is to be used for config dump and CSDS, not directly by users (like
|
||||
// resolvers/balancers).
|
||||
type UpdateWithMD struct { |
||||
MD UpdateMetadata |
||||
Raw *anypb.Any |
||||
} |
||||
|
||||
// ResourceType identifies resources in a transport protocol agnostic way. These
|
||||
// will be used in transport version agnostic code, while the versioned API
|
||||
// clients will map these to appropriate version URLs.
|
||||
type ResourceType int |
||||
|
||||
// Version agnostic resource type constants.
|
||||
const ( |
||||
UnknownResource ResourceType = iota |
||||
ListenerResource |
||||
HTTPConnManagerResource |
||||
RouteConfigResource |
||||
ClusterResource |
||||
EndpointsResource |
||||
) |
||||
|
||||
func (r ResourceType) String() string { |
||||
switch r { |
||||
case ListenerResource: |
||||
return "ListenerResource" |
||||
case HTTPConnManagerResource: |
||||
return "HTTPConnManagerResource" |
||||
case RouteConfigResource: |
||||
return "RouteConfigResource" |
||||
case ClusterResource: |
||||
return "ClusterResource" |
||||
case EndpointsResource: |
||||
return "EndpointsResource" |
||||
default: |
||||
return "UnknownResource" |
||||
} |
||||
} |
@ -0,0 +1,63 @@ |
||||
/* |
||||
* |
||||
* Copyright 2020 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
// Package version defines constants to distinguish between supported xDS API
|
||||
// versions.
|
||||
package resource |
||||
|
||||
// TransportAPI refers to the API version for xDS transport protocol. This
|
||||
// describes the xDS gRPC endpoint and version of DiscoveryRequest/Response used
|
||||
// on the wire.
|
||||
type TransportAPI int |
||||
|
||||
const ( |
||||
// TransportV2 refers to the v2 xDS transport protocol.
|
||||
TransportV2 TransportAPI = iota |
||||
// TransportV3 refers to the v3 xDS transport protocol.
|
||||
TransportV3 |
||||
) |
||||
|
||||
// Resource URLs. We need to be able to accept either version of the resource
|
||||
// regardless of the version of the transport protocol in use.
|
||||
const ( |
||||
googleapiPrefix = "type.googleapis.com/" |
||||
|
||||
V2ListenerType = "envoy.api.v2.Listener" |
||||
V2RouteConfigType = "envoy.api.v2.RouteConfiguration" |
||||
V2ClusterType = "envoy.api.v2.Cluster" |
||||
V2EndpointsType = "envoy.api.v2.ClusterLoadAssignment" |
||||
|
||||
V2ListenerURL = googleapiPrefix + V2ListenerType |
||||
V2RouteConfigURL = googleapiPrefix + V2RouteConfigType |
||||
V2ClusterURL = googleapiPrefix + V2ClusterType |
||||
V2EndpointsURL = googleapiPrefix + V2EndpointsType |
||||
V2HTTPConnManagerURL = googleapiPrefix + "envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager" |
||||
|
||||
V3ListenerType = "envoy.config.listener.v3.Listener" |
||||
V3RouteConfigType = "envoy.config.route.v3.RouteConfiguration" |
||||
V3ClusterType = "envoy.config.cluster.v3.Cluster" |
||||
V3EndpointsType = "envoy.config.endpoint.v3.ClusterLoadAssignment" |
||||
|
||||
V3ListenerURL = googleapiPrefix + V3ListenerType |
||||
V3RouteConfigURL = googleapiPrefix + V3RouteConfigType |
||||
V3ClusterURL = googleapiPrefix + V3ClusterType |
||||
V3EndpointsURL = googleapiPrefix + V3EndpointsType |
||||
V3HTTPConnManagerURL = googleapiPrefix + "envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager" |
||||
V3UpstreamTLSContextURL = googleapiPrefix + "envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext" |
||||
V3DownstreamTLSContextURL = googleapiPrefix + "envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext" |
||||
) |
Loading…
Reference in new issue