selector: use custom domain (#1760)

* util/wrapper: improve auth errors

* client: add network call option

* client/selector: add domain select option

* client/grpc: pass network option to selector
This commit is contained in:
ben-toogood 2020-06-30 10:07:52 +01:00 committed by GitHub
parent deea8fecf4
commit 0f5c53b6e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 42 additions and 7 deletions

View File

@ -84,8 +84,14 @@ func (g *grpcClient) next(request client.Request, opts client.CallOptions) (sele
}, nil
}
// if the network was set, pass it to the selector
sopts := opts.SelectOptions
if len(opts.Network) > 0 {
sopts = append(sopts, selector.WithDomain(opts.Network))
}
// get next nodes from the selector
next, err := g.opts.Selector.Select(service, opts.SelectOptions...)
next, err := g.opts.Selector.Select(service, sopts...)
if err != nil {
if err == selector.ErrNotFound {
return nil, errors.InternalServerError("go.micro.client", "service %s: %s", service, err.Error())

View File

@ -64,6 +64,8 @@ type CallOptions struct {
ServiceToken bool
// Duration to cache the response for
CacheExpiry time.Duration
// Network to lookup the route within
Network string
// Middleware for low level call func
CallWrappers []CallWrapper
@ -338,6 +340,13 @@ func WithCache(c time.Duration) CallOption {
}
}
// WithNetwork is a CallOption which sets the network attribute
func WithNetwork(n string) CallOption {
return func(o *CallOptions) {
o.Network = n
}
}
func WithMessageContentType(ct string) MessageOption {
return func(o *MessageOptions) {
o.ContentType = ct

View File

@ -38,14 +38,26 @@ func (c *registrySelector) Options() Options {
}
func (c *registrySelector) Select(service string, opts ...SelectOption) (Next, error) {
sopts := SelectOptions{
Strategy: c.so.Strategy,
}
sopts := SelectOptions{Strategy: c.so.Strategy}
for _, opt := range opts {
opt(&sopts)
}
// a specific domain was requested, only lookup the services in that domain
if len(sopts.Domain) > 0 {
services, err := c.rc.GetService(service, registry.GetDomain(sopts.Domain))
if err != nil && err != registry.ErrNotFound {
return nil, err
}
for _, filter := range sopts.Filters {
services = filter(services)
}
if len(services) == 0 {
return nil, ErrNoneAvailable
}
return sopts.Strategy(services), nil
}
// get the service. Because the service could be running in the current or the default domain,
// we call both. For example, go.micro.service.foo could be running in the services current domain,
// however the runtime (go.micro.runtime) will always be run in the default domain.

View File

@ -21,6 +21,7 @@ type Options struct {
type SelectOptions struct {
Filters []Filter
Strategy Strategy
Domain string
// Other options for implementations of the interface
// can be stored in a context
@ -68,3 +69,10 @@ func WithStrategy(fn Strategy) SelectOption {
o.Strategy = fn
}
}
// WithDomain sets the registry domain to use for the selection
func WithDomain(d string) SelectOption {
return func(o *SelectOptions) {
o.Domain = d
}
}

View File

@ -222,10 +222,10 @@ func AuthHandler(fn func() auth.Auth) server.HandlerWrapper {
ctx = metadata.Set(ctx, "Micro-Namespace", ns)
}
// Check the issuer matches the services namespace. TODO: Stop allowing go.micro to access
// Check the issuer matches the services namespace. TODO: Stop allowing micro to access
// any namespace and instead check for the server issuer.
if account != nil && account.Issuer != ns && account.Issuer != "micro" {
return errors.Forbidden(req.Service(), "Account was not issued by %v", ns)
return errors.Forbidden(req.Service(), "Account was issued by %v, not %v", account.Issuer, ns)
}
// construct the resource