Files
weave-scope/vendor/github.com/sercand/kuberesolver/balancer.go
Marc CARRE 4439e6f717 Update weaveworks/common to latest.
```
$ gvt delete github.com/weaveworks/common
$ gvt fetch -revision 15746cbb5831e70c58d520634b09393b7c3cfd56 github.com/weaveworks/common
2017/10/08 XX:XX:XX Fetching: github.com/weaveworks/common
2017/10/08 XX:XX:XX · Skipping (existing): github.com/sirupsen/logrus
2017/10/08 XX:XX:XX · Skipping (existing): github.com/golang/protobuf/proto
2017/10/08 XX:XX:XX · Skipping (existing): github.com/mgutz/ansi
2017/10/08 XX:XX:XX · Skipping (existing): golang.org/x/net/context
2017/10/08 XX:XX:XX · Skipping (existing): github.com/opentracing/opentracing-go/ext
2017/10/08 XX:XX:XX · Skipping (existing): github.com/golang/protobuf/ptypes/empty
2017/10/08 XX:XX:XX · Fetching recursive dependency: github.com/opentracing-contrib/go-stdlib/nethttp
2017/10/08 XX:XX:XX ·· Skipping (existing): github.com/opentracing/opentracing-go
2017/10/08 XX:XX:XX ·· Skipping (existing): github.com/opentracing/opentracing-go/ext
2017/10/08 XX:XX:XX ·· Skipping (existing): github.com/opentracing/opentracing-go/log
2017/10/08 XX:XX:XX · Skipping (existing): github.com/aws/aws-sdk-go/aws/credentials
2017/10/08 XX:XX:XX · Skipping (existing): github.com/weaveworks/promrus
2017/10/08 XX:XX:XX · Skipping (existing): github.com/golang/protobuf/ptypes
2017/10/08 XX:XX:XX · Fetching recursive dependency: github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc
2017/10/08 XX:XX:XX ·· Skipping (existing): github.com/opentracing/opentracing-go
2017/10/08 XX:XX:XX ·· Skipping (existing): github.com/opentracing/opentracing-go/ext
2017/10/08 XX:XX:XX ·· Skipping (existing): google.golang.org/grpc/metadata
2017/10/08 XX:XX:XX ·· Skipping (existing): google.golang.org/grpc/codes
2017/10/08 XX:XX:XX ·· Skipping (existing): google.golang.org/grpc/status
2017/10/08 XX:XX:XX ·· Skipping (existing): github.com/opentracing/opentracing-go/log
2017/10/08 XX:XX:XX ·· Skipping (existing): golang.org/x/net/context
2017/10/08 XX:XX:XX ·· Skipping (existing): google.golang.org/grpc
2017/10/08 XX:XX:XX · Skipping (existing): golang.org/x/tools/cover
2017/10/08 XX:XX:XX · Skipping (existing): github.com/aws/aws-sdk-go/aws
2017/10/08 XX:XX:XX · Skipping (existing): github.com/armon/go-socks5
2017/10/08 XX:XX:XX · Fetching recursive dependency: github.com/weaveworks-experiments/loki/pkg/client
2017/10/08 XX:XX:XX ·· Fetching recursive dependency: github.com/weaveworks-experiments/loki/vendor/github.com/apache/thrift/lib/go/thrift
2017/10/08 XX:XX:XX ·· Fetching recursive dependency: github.com/weaveworks-experiments/loki/vendor/github.com/opentracing/opentracing-go
2017/10/08 XX:XX:XX ··· Fetching recursive dependency: github.com/weaveworks-experiments/loki/vendor/golang.org/x/net/context
2017/10/08 XX:XX:XX ·· Fetching recursive dependency: github.com/weaveworks-experiments/loki/vendor/github.com/openzipkin/zipkin-go-opentracing
2017/10/08 XX:XX:XX ··· Fetching recursive dependency: github.com/weaveworks-experiments/loki/vendor/github.com/gogo/protobuf/proto
2017/10/08 XX:XX:XX ··· Fetching recursive dependency: github.com/weaveworks-experiments/loki/vendor/github.com/Shopify/sarama
2017/10/08 XX:XX:XX ···· Fetching recursive dependency: github.com/weaveworks-experiments/loki/vendor/github.com/eapache/queue
2017/10/08 XX:XX:XX ···· Fetching recursive dependency: github.com/weaveworks-experiments/loki/vendor/github.com/eapache/go-xerial-snappy
2017/10/08 XX:XX:XX ····· Fetching recursive dependency: github.com/weaveworks-experiments/loki/vendor/github.com/golang/snappy
2017/10/08 XX:XX:XX ···· Fetching recursive dependency: github.com/weaveworks-experiments/loki/vendor/github.com/pierrec/lz4
2017/10/08 XX:XX:XX ····· Fetching recursive dependency: github.com/weaveworks-experiments/loki/vendor/github.com/pierrec/xxHash/xxHash32
2017/10/08 XX:XX:XX ···· Fetching recursive dependency: github.com/weaveworks-experiments/loki/vendor/github.com/eapache/go-resiliency/breaker
2017/10/08 XX:XX:XX ···· Fetching recursive dependency: github.com/weaveworks-experiments/loki/vendor/github.com/klauspost/crc32
2017/10/08 XX:XX:XX ···· Fetching recursive dependency: github.com/weaveworks-experiments/loki/vendor/github.com/davecgh/go-spew/spew
2017/10/08 XX:XX:XX ···· Fetching recursive dependency: github.com/weaveworks-experiments/loki/vendor/github.com/rcrowley/go-metrics
2017/10/08 XX:XX:XX ··· Fetching recursive dependency: github.com/weaveworks-experiments/loki/vendor/github.com/go-logfmt/logfmt
2017/10/08 XX:XX:XX ···· Fetching recursive dependency: github.com/weaveworks-experiments/loki/vendor/github.com/kr/logfmt
2017/10/08 XX:XX:XX · Skipping (existing): google.golang.org/grpc/metadata
2017/10/08 XX:XX:XX · Fetching recursive dependency: github.com/mwitkow/go-grpc-middleware
2017/10/08 XX:XX:XX ·· Skipping (existing): google.golang.org/grpc/grpclog
2017/10/08 XX:XX:XX ·· Fetching recursive dependency: go.uber.org/zap/zapcore
2017/10/08 XX:XX:XX ··· Fetching recursive dependency: go.uber.org/zap/internal/exit
2017/10/08 XX:XX:XX ··· Fetching recursive dependency: go.uber.org/multierr
2017/10/08 XX:XX:XX ···· Fetching recursive dependency: go.uber.org/atomic
2017/10/08 XX:XX:XX ··· Fetching recursive dependency: go.uber.org/zap/internal/color
2017/10/08 XX:XX:XX ··· Fetching recursive dependency: go.uber.org/zap/buffer
2017/10/08 XX:XX:XX ··· Fetching recursive dependency: go.uber.org/zap/internal/bufferpool
2017/10/08 XX:XX:XX ·· Skipping (existing): google.golang.org/grpc/metadata
2017/10/08 XX:XX:XX ·· Fetching recursive dependency: github.com/grpc-ecosystem/go-grpc-middleware/testing/testproto
2017/10/08 XX:XX:XX ··· Skipping (existing): github.com/golang/protobuf/proto
2017/10/08 XX:XX:XX ··· Skipping (existing): golang.org/x/net/context
2017/10/08 XX:XX:XX ··· Skipping (existing): google.golang.org/grpc
2017/10/08 XX:XX:XX ·· Skipping (existing): github.com/opentracing/opentracing-go
2017/10/08 XX:XX:XX ·· Skipping (existing): github.com/opentracing/opentracing-go/log
2017/10/08 XX:XX:XX ·· Skipping (existing): golang.org/x/net/context
2017/10/08 XX:XX:XX ·· Skipping (existing): github.com/sirupsen/logrus
2017/10/08 XX:XX:XX ·· Fetching recursive dependency: github.com/golang/protobuf/jsonpb
2017/10/08 XX:XX:XX ··· Skipping (existing): github.com/golang/protobuf/proto
2017/10/08 XX:XX:XX ··· Skipping (existing): github.com/golang/protobuf/ptypes/any
2017/10/08 XX:XX:XX ··· Skipping (existing): github.com/golang/protobuf/ptypes/struct
2017/10/08 XX:XX:XX ··· Skipping (existing): github.com/golang/protobuf/ptypes/duration
2017/10/08 XX:XX:XX ··· Skipping (existing): github.com/golang/protobuf/ptypes/timestamp
2017/10/08 XX:XX:XX ··· Skipping (existing): github.com/golang/protobuf/ptypes/wrappers
2017/10/08 XX:XX:XX ·· Skipping (existing): golang.org/x/net/trace
2017/10/08 XX:XX:XX ·· Skipping (existing): google.golang.org/grpc
2017/10/08 XX:XX:XX ·· Skipping (existing): google.golang.org/grpc/credentials
2017/10/08 XX:XX:XX ·· Fetching recursive dependency: github.com/grpc-ecosystem/go-grpc-middleware/logging
2017/10/08 XX:XX:XX ··· Skipping (existing): google.golang.org/grpc/grpclog
2017/10/08 XX:XX:XX ··· Fetching recursive dependency: go.uber.org/zap
2017/10/08 XX:XX:XX ··· Skipping (existing): github.com/sirupsen/logrus
2017/10/08 XX:XX:XX ··· Skipping (existing): google.golang.org/grpc/codes
2017/10/08 XX:XX:XX ··· Fetching recursive dependency: github.com/grpc-ecosystem/go-grpc-middleware/tags
2017/10/08 XX:XX:XX ···· Skipping (existing): google.golang.org/grpc/peer
2017/10/08 XX:XX:XX ···· Fetching recursive dependency: github.com/grpc-ecosystem/go-grpc-middleware
2017/10/08 XX:XX:XX ····· Skipping (existing): github.com/opentracing/opentracing-go/log
2017/10/08 XX:XX:XX ····· Skipping (existing): golang.org/x/net/context
2017/10/08 XX:XX:XX ····· Skipping (existing): google.golang.org/grpc
2017/10/08 XX:XX:XX ····· Skipping (existing): github.com/golang/protobuf/proto
2017/10/08 XX:XX:XX ····· Skipping (existing): google.golang.org/grpc/metadata
2017/10/08 XX:XX:XX ····· Fetching recursive dependency: github.com/stretchr/testify/suite
2017/10/08 XX:XX:XX ······ Skipping (existing): github.com/stretchr/testify/assert
2017/10/08 XX:XX:XX ······ Fetching recursive dependency: github.com/stretchr/testify/require
2017/10/08 XX:XX:XX ······· Skipping (existing): github.com/stretchr/testify/assert
2017/10/08 XX:XX:XX ····· Skipping (existing): github.com/opentracing/opentracing-go
2017/10/08 XX:XX:XX ····· Skipping (existing): github.com/sirupsen/logrus
2017/10/08 XX:XX:XX ····· Fetching recursive dependency: github.com/gogo/protobuf/gogoproto
2017/10/08 XX:XX:XX ······ Fetching recursive dependency: github.com/gogo/protobuf/proto
2017/10/08 XX:XX:XX ······· Fetching recursive dependency: github.com/gogo/protobuf/types
2017/10/08 XX:XX:XX ········ Fetching recursive dependency: github.com/gogo/protobuf/sortkeys
2017/10/08 XX:XX:XX ······ Fetching recursive dependency: github.com/gogo/protobuf/protoc-gen-gogo/descriptor
2017/10/08 XX:XX:XX ····· Skipping (existing): google.golang.org/grpc/codes
2017/10/08 XX:XX:XX ····· Skipping (existing): github.com/opentracing/opentracing-go/ext
2017/10/08 XX:XX:XX ····· Skipping (existing): google.golang.org/grpc/grpclog
2017/10/08 XX:XX:XX ····· Skipping (existing): google.golang.org/grpc/peer
2017/10/08 XX:XX:XX ····· Skipping (existing): golang.org/x/net/trace
2017/10/08 XX:XX:XX ····· Skipping (existing): google.golang.org/grpc/credentials
2017/10/08 XX:XX:XX ···· Skipping (existing): golang.org/x/net/context
2017/10/08 XX:XX:XX ···· Skipping (existing): google.golang.org/grpc
2017/10/08 XX:XX:XX ··· Skipping (existing): github.com/golang/protobuf/proto
2017/10/08 XX:XX:XX ··· Skipping (existing): golang.org/x/net/context
2017/10/08 XX:XX:XX ··· Skipping (existing): google.golang.org/grpc
2017/10/08 XX:XX:XX ·· Skipping (existing): github.com/opentracing/opentracing-go/ext
2017/10/08 XX:XX:XX ·· Skipping (existing): github.com/golang/protobuf/proto
2017/10/08 XX:XX:XX ·· Skipping (existing): google.golang.org/grpc/codes
2017/10/08 XX:XX:XX ·· Skipping (existing): google.golang.org/grpc/peer
2017/10/08 XX:XX:XX · Skipping (existing): github.com/davecgh/go-spew/spew
2017/10/08 XX:XX:XX · Skipping (existing): google.golang.org/grpc/status
2017/10/08 XX:XX:XX · Skipping (existing): google.golang.org/grpc
2017/10/08 XX:XX:XX · Skipping (existing): github.com/golang/protobuf/ptypes/any
2017/10/08 XX:XX:XX · Skipping (existing): github.com/opentracing/opentracing-go
2017/10/08 XX:XX:XX · Skipping (existing): github.com/prometheus/client_golang/prometheus
2017/10/08 XX:XX:XX · Fetching recursive dependency: google.golang.org/genproto/googleapis/rpc/status
2017/10/08 XX:XX:XX ·· Skipping (existing): github.com/golang/protobuf/proto
2017/10/08 XX:XX:XX ·· Skipping (existing): github.com/golang/protobuf/ptypes/any
2017/10/08 XX:XX:XX · Skipping (existing): github.com/pmezard/go-difflib/difflib
2017/10/08 XX:XX:XX · Fetching recursive dependency: github.com/sercand/kuberesolver
2017/10/08 XX:XX:XX ·· Skipping (existing): google.golang.org/grpc/naming
2017/10/08 XX:XX:XX ·· Skipping (existing): google.golang.org/grpc/grpclog
2017/10/08 XX:XX:XX ·· Skipping (existing): google.golang.org/grpc
2017/10/08 XX:XX:XX · Skipping (existing): github.com/gorilla/mux
```
2017-10-08 18:37:28 +01:00

136 lines
3.2 KiB
Go

package kuberesolver
import (
"errors"
"fmt"
"net/url"
"strconv"
"strings"
"google.golang.org/grpc"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/naming"
)
type Balancer struct {
Namespace string
client *k8sClient
resolvers []*kubeResolver
}
type TargetUrlType int32
const (
TargetTypeDNS TargetUrlType = 0
TargetTypeKubernetes TargetUrlType = 1
kubernetesSchema = "kubernetes"
dnsSchema = "dns"
)
type targetInfo struct {
urlType TargetUrlType
target string
port string
resolveByPortName bool
useFirstPort bool
}
func parseTarget(target string) (targetInfo, error) {
u, err := url.Parse(target)
if err != nil {
return targetInfo{}, err
}
ti := targetInfo{}
if u.Scheme == kubernetesSchema {
ti.urlType = TargetTypeKubernetes
spl := strings.Split(u.Host, ":")
if len(spl) == 2 {
ti.target = spl[0]
ti.port = spl[1]
ti.useFirstPort = false
if _, err := strconv.Atoi(ti.port); err != nil {
ti.resolveByPortName = true
} else {
ti.resolveByPortName = false
}
} else {
ti.target = spl[0]
ti.useFirstPort = true
}
} else if u.Scheme == dnsSchema {
ti.urlType = TargetTypeDNS
ti.target = u.Host
} else {
ti.urlType = TargetTypeDNS
ti.target = target
}
return ti, nil
}
//Resolver returns Resolver for grpc
func (b *Balancer) Resolver() naming.Resolver {
return newResolver(b.client, b.Namespace)
}
//DialOption returns grpc.DialOption with RoundRobin balancer and resolver
func (b *Balancer) DialOption() grpc.DialOption {
rs := newResolver(b.client, b.Namespace)
return grpc.WithBalancer(grpc.RoundRobin(rs))
}
// Dial calls grpc.Dial, also parses target and uses load balancer if necessary
func (b *Balancer) Dial(target string, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
pt, err := parseTarget(target)
if err != nil {
return nil, err
}
switch pt.urlType {
case TargetTypeKubernetes:
if b.client == nil {
return nil, errors.New("application is not running inside kubernetes")
}
grpclog.Printf("kuberesolver: using kubernetes resolver target=%s", pt.target)
rs := newResolver(b.client, b.Namespace)
b.resolvers = append(b.resolvers, rs)
opts := append(opts, grpc.WithBalancer(grpc.RoundRobin(rs)))
return grpc.Dial(target, opts...)
case TargetTypeDNS:
return grpc.Dial(pt.target, opts...)
default:
return nil, errors.New("Unknown target type")
}
}
func (b *Balancer) Healthy() error {
for _, r := range b.resolvers {
if r.watcher != nil {
if len(r.watcher.endpoints) == 0 {
return fmt.Errorf("target does not have endpoints")
}
}
}
return nil
}
// IsInCluster returns true if application is running inside kubernetes cluster
func (b *Balancer) IsInCluster() bool {
return b.client != nil
}
// New creates a Balancer with "default" namespace
func New() *Balancer {
return NewWithNamespace("default")
}
// NewWithNamespace creates a Balancer with given namespace.
func NewWithNamespace(namespace string) *Balancer {
client, err := newInClusterClient()
if err != nil {
grpclog.Printf("kuberesolver: application is not running inside kubernetes")
}
return &Balancer{
Namespace: namespace,
client: client,
}
}