mirror of
https://github.com/coredns/coredns.git
synced 2025-10-27 08:14:18 -04:00
102 lines
3.4 KiB
Go
102 lines
3.4 KiB
Go
/*
|
|
*
|
|
* Copyright 2019 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 client implementation a full fledged gRPC client for the xDS API
|
|
// used by the xds resolver and balancer implementations.
|
|
package xds
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/coredns/coredns/plugin/traffic/xds/bootstrap"
|
|
|
|
"google.golang.org/grpc"
|
|
)
|
|
|
|
// Options provides all parameters required for the creation of an xDS client.
|
|
type Options struct {
|
|
// Config contains a fully populated bootstrap config. It is the
|
|
// responsibility of the caller to use some sane defaults here if the
|
|
// bootstrap process returned with certain fields left unspecified.
|
|
Config bootstrap.Config
|
|
// DialOpts contains dial options to be used when dialing the xDS server.
|
|
DialOpts []grpc.DialOption
|
|
}
|
|
|
|
// Client is a full fledged gRPC client which queries a set of discovery APIs
|
|
// (collectively termed as xDS) on a remote management server, to discover
|
|
// various dynamic resources. A single client object will be shared by the xds
|
|
// resolver and balancer implementations.
|
|
type Client struct {
|
|
opts Options
|
|
cc *grpc.ClientConn // Connection to the xDS server
|
|
v2c *v2Client // Actual xDS client implementation using the v2 API
|
|
|
|
serviceCallback func(ServiceUpdate, error)
|
|
}
|
|
|
|
// New returns a new xdsClient configured with opts.
|
|
func New(opts Options) (*Client, error) {
|
|
switch {
|
|
case opts.Config.BalancerName == "":
|
|
return nil, errors.New("xds: no xds_server name provided in options")
|
|
case opts.Config.Creds == nil:
|
|
return nil, errors.New("xds: no credentials provided in options")
|
|
case opts.Config.NodeProto == nil:
|
|
return nil, errors.New("xds: no node_proto provided in options")
|
|
}
|
|
|
|
dopts := append([]grpc.DialOption{opts.Config.Creds}, opts.DialOpts...)
|
|
cc, err := grpc.Dial(opts.Config.BalancerName, dopts...)
|
|
if err != nil {
|
|
// An error from a non-blocking dial indicates something serious.
|
|
return nil, fmt.Errorf("xds: failed to dial balancer {%s}: %v", opts.Config.BalancerName, err)
|
|
}
|
|
|
|
c := &Client{
|
|
opts: opts,
|
|
cc: cc,
|
|
v2c: newV2Client(cc, opts.Config.NodeProto, nil), // todo re-add backoff (exponential)
|
|
}
|
|
return c, nil
|
|
}
|
|
|
|
// Close closes the gRPC connection to the xDS server.
|
|
func (c *Client) Close() {
|
|
// TODO: Should we invoke the registered callbacks here with an error that
|
|
// the client is closed?
|
|
c.v2c.close()
|
|
c.cc.Close()
|
|
}
|
|
|
|
// ServiceUpdate contains update about the service.
|
|
type ServiceUpdate struct {
|
|
Cluster string
|
|
}
|
|
|
|
// WatchCluster uses CDS to discover information about the provided clusterName.
|
|
func (c *Client) WatchCluster(clusterName string, cdsCb func(CDSUpdate, error)) (cancel func()) {
|
|
return c.v2c.watchCDS(clusterName, cdsCb)
|
|
}
|
|
|
|
// WatchEndpoints uses EDS to discover information about the endpoints in a cluster.
|
|
func (c *Client) WatchEndpoints(clusterName string, edsCb func(*EDSUpdate, error)) (cancel func()) {
|
|
return c.v2c.watchEDS(clusterName, edsCb)
|
|
}
|