Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates for compatibility with new gRPC target interface #36

Merged
merged 1 commit into from
Mar 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 42 additions & 37 deletions builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,50 +73,55 @@ type kubeBuilder struct {
schema string
}

func parseResolverTarget(target resolver.Target) (targetInfo, error) {
// kubernetes://default/service:port
end := target.Endpoint
snamespace := target.Authority
// kubernetes://service.default:port/
if end == "" {
end = target.Authority
snamespace = ""
func splitServicePortNamespace(hpn string) (service, port, namespace string) {
service = hpn

colon := strings.LastIndexByte(service, ':')
if colon != -1 {
service, port = service[:colon], service[colon+1:]
}
ti := targetInfo{}
if end == "" {
return targetInfo{}, fmt.Errorf("target(%q) is empty", target)

dot := strings.LastIndexByte(service, '.')
if dot != -1 {
service, namespace = service[:dot], service[dot+1:]
}
var name string
var port string
if strings.LastIndex(end, ":") < 0 {
name = end
port = ""
ti.useFirstPort = true

return
}

func parseResolverTarget(target resolver.Target) (targetInfo, error) {
var service, port, namespace string
if target.URL.Host == "" {
// kubernetes:///service.namespace:port
service, port, namespace = splitServicePortNamespace(target.Endpoint())
} else if target.URL.Port() == "" && target.Endpoint() != "" {
// kubernetes://namespace/service:port
service, port, _ = splitServicePortNamespace(target.Endpoint())
namespace = target.URL.Hostname()
} else {
var err error
name, port, err = net.SplitHostPort(end)
if err != nil {
return targetInfo{}, fmt.Errorf("target endpoint='%s' is invalid. grpc target is %#v, err=%v", end, target, err)
}
// kubernetes://service.namespace:port
service, port, namespace = splitServicePortNamespace(target.URL.Host)
}

namesplit := strings.SplitN(name, ".", 2)
sname := name
if len(namesplit) == 2 {
sname = namesplit[0]
snamespace = namesplit[1]
if service == "" {
return targetInfo{}, fmt.Errorf("target %s must specify a service", &target.URL)
}
ti.serviceName = sname
ti.serviceNamespace = snamespace
ti.port = port
if !ti.useFirstPort {
if _, err := strconv.Atoi(ti.port); err != nil {
ti.resolveByPortName = true
} else {
ti.resolveByPortName = false
}

resolveByPortName := false
useFirstPort := false
if port == "" {
useFirstPort = true
} else if _, err := strconv.Atoi(port); err != nil {
resolveByPortName = true
}
return ti, nil

return targetInfo{
serviceName: service,
serviceNamespace: namespace,
port: port,
resolveByPortName: resolveByPortName,
useFirstPort: useFirstPort,
}, nil
}

// Build creates a new resolver for the given target.
Expand Down
62 changes: 31 additions & 31 deletions builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package kuberesolver
import (
"fmt"
"log"
"net/url"
"strings"
"testing"

Expand All @@ -20,8 +21,8 @@ type fakeConn struct {
found []string
}

func (fc *fakeConn) UpdateState(resolver.State) {

func (fc *fakeConn) UpdateState(resolver.State) error {
return nil
}

func (fc *fakeConn) ReportError(e error) {
Expand Down Expand Up @@ -54,7 +55,7 @@ func TestBuilder(t *testing.T) {
fc := &fakeConn{
cmp: make(chan struct{}),
}
rs, err := bl.Build(resolver.Target{Endpoint: "kube-dns.kube-system:53", Scheme: "kubernetes", Authority: ""}, fc, resolver.BuildOptions{})
rs, err := bl.Build(parseTarget("kubernetes://kube-dns.kube-system:53"), fc, resolver.BuildOptions{})
if err != nil {
t.Fatal(err)
}
Expand All @@ -80,22 +81,22 @@ func split2(s, sep string) (string, string, bool) {
return spl[0], spl[1], true
}

// ParseTarget splits target into a resolver.Target struct containing scheme,
// authority and endpoint.
//
// If target is not a valid scheme://authority/endpoint, it returns {Endpoint:
// target}.
func parseTarget(target string) (ret resolver.Target) {
var ok bool
ret.Scheme, ret.Endpoint, ok = split2(target, "://")
if !ok {
return resolver.Target{Endpoint: target}
func parseTarget(target string) resolver.Target {
u, err := url.Parse(target)
if err != nil {
panic(err)
}
ret.Authority, ret.Endpoint, ok = split2(ret.Endpoint, "/")
if !ok {
return resolver.Target{Endpoint: target}

scheme := u.Scheme
if scheme == "" {
scheme = "kubernetes"
}

return resolver.Target{
Scheme: scheme,
Authority: u.Host,
URL: *u,
}
return ret
}

func TestParseResolverTarget(t *testing.T) {
Expand All @@ -104,17 +105,17 @@ func TestParseResolverTarget(t *testing.T) {
want targetInfo
err bool
}{
{resolver.Target{"", "", ""}, targetInfo{"", "", "", false, false}, true},
{resolver.Target{"", "a", ""}, targetInfo{"a", "", "", false, true}, false},
{resolver.Target{"", "", "a"}, targetInfo{"a", "", "", false, true}, false},
{resolver.Target{"", "a", "b"}, targetInfo{"b", "a", "", false, true}, false},
{resolver.Target{"", "a.b", ""}, targetInfo{"a", "b", "", false, true}, false},
{resolver.Target{"", "", "a.b"}, targetInfo{"a", "b", "", false, true}, false},
{resolver.Target{"", "", "a.b:80"}, targetInfo{"a", "b", "80", false, false}, false},
{resolver.Target{"", "", "a.b:port"}, targetInfo{"a", "b", "port", true, false}, false},
{resolver.Target{"", "a", "b:port"}, targetInfo{"b", "a", "port", true, false}, false},
{resolver.Target{"", "b.a:port", ""}, targetInfo{"b", "a", "port", true, false}, false},
{resolver.Target{"", "b.a:80", ""}, targetInfo{"b", "a", "80", false, false}, false},
{parseTarget("/"), targetInfo{"", "", "", false, false}, true},
{parseTarget("a"), targetInfo{"a", "", "", false, true}, false},
{parseTarget("/a"), targetInfo{"a", "", "", false, true}, false},
{parseTarget("//a/b"), targetInfo{"b", "a", "", false, true}, false},
{parseTarget("a.b"), targetInfo{"a", "b", "", false, true}, false},
{parseTarget("/a.b"), targetInfo{"a", "b", "", false, true}, false},
{parseTarget("/a.b:80"), targetInfo{"a", "b", "80", false, false}, false},
{parseTarget("/a.b:port"), targetInfo{"a", "b", "port", true, false}, false},
{parseTarget("//a/b:port"), targetInfo{"b", "a", "port", true, false}, false},
{parseTarget("//a/b:port"), targetInfo{"b", "a", "port", true, false}, false},
{parseTarget("//a/b:80"), targetInfo{"b", "a", "80", false, false}, false},
} {
got, err := parseResolverTarget(test.target)
if err == nil && test.err {
Expand All @@ -126,7 +127,7 @@ func TestParseResolverTarget(t *testing.T) {
continue
}
if got != test.want {
t.Errorf("case %d parseTarget(%q) = %+v, want %+v", i, test.target, got, test.want)
t.Errorf("case %d parseResolverTarget(%q) = %+v, want %+v", i, &test.target.URL, got, test.want)
}
}
}
Expand All @@ -139,7 +140,7 @@ func TestParseTargets(t *testing.T) {
}{
{"", targetInfo{}, true},
{"kubernetes:///", targetInfo{}, true},
{"kubernetes://a:30", targetInfo{}, true},
{"kubernetes://a:30", targetInfo{"a", "", "30", false, false}, false},
{"kubernetes://a/", targetInfo{"a", "", "", false, true}, false},
{"kubernetes:///a", targetInfo{"a", "", "", false, true}, false},
{"kubernetes://a/b", targetInfo{"b", "a", "", false, true}, false},
Expand All @@ -148,7 +149,6 @@ func TestParseTargets(t *testing.T) {
{"kubernetes:///a.b:port", targetInfo{"a", "b", "port", true, false}, false},
{"kubernetes:///a:port", targetInfo{"a", "", "port", true, false}, false},
{"kubernetes://x/a:port", targetInfo{"a", "x", "port", true, false}, false},
{"kubernetes://a.x:port/", targetInfo{"a", "x", "port", true, false}, false},
{"kubernetes://a.x:30/", targetInfo{"a", "x", "30", false, false}, false},
} {
got, err := parseResolverTarget(parseTarget(test.target))
Expand Down
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
module github.com/sercand/kuberesolver/v3
module github.com/sercand/kuberesolver/v4

go 1.14

require (
github.com/fsnotify/fsnotify v1.5.4
github.com/prometheus/client_golang v1.7.1
google.golang.org/grpc v1.31.0
golang.org/x/sys v0.5.0 // indirect
google.golang.org/grpc v1.53.0
)
Loading