pomerium/pkg/grpc/resolver.go
dependabot[bot] e9ffc5fde3
chore(deps): bump google.golang.org/grpc from 1.37.1 to 1.38.0 (#2231)
* chore(deps): bump google.golang.org/grpc from 1.37.1 to 1.38.0

Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.37.1 to 1.38.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.37.1...v1.38.0)

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): bump google.golang.org/grpc from 1.37.1 to 1.38.0

Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.37.1 to 1.38.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.37.1...v1.38.0)

Signed-off-by: dependabot[bot] <support@github.com>

* fix UpdateState method

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Caleb Doxsey <cdoxsey@pomerium.com>
2021-05-24 09:33:53 -06:00

104 lines
2.2 KiB
Go

package grpc
import (
"strings"
"sync"
"google.golang.org/grpc/resolver"
)
func init() {
resolver.Register(&pomeriumBuilder{})
}
type pomeriumBuilder struct {
}
func (*pomeriumBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
endpoints := strings.Split(target.Endpoint, ",")
pccd := &pomeriumClientConnData{
states: make([]resolver.State, len(endpoints)),
}
pr := &pomeriumResolver{}
for i, endpoint := range endpoints {
subTarget := parseTarget(endpoint)
b := resolver.Get(subTarget.Scheme)
pcc := &pomeriumClientConn{
data: pccd,
idx: i,
ClientConn: cc,
}
r, err := b.Build(subTarget, pcc, opts)
if err != nil {
return nil, err
}
pr.resolvers = append(pr.resolvers, r)
}
return pr, nil
}
func (*pomeriumBuilder) Scheme() string {
return "pomerium"
}
type pomeriumResolver struct {
resolvers []resolver.Resolver
}
func (pr *pomeriumResolver) ResolveNow(options resolver.ResolveNowOptions) {
for _, r := range pr.resolvers {
r.ResolveNow(options)
}
}
func (pr *pomeriumResolver) Close() {
for _, r := range pr.resolvers {
r.Close()
}
}
type pomeriumClientConn struct {
data *pomeriumClientConnData
idx int
resolver.ClientConn
}
func (pcc *pomeriumClientConn) UpdateState(state resolver.State) error {
return pcc.ClientConn.UpdateState(pcc.data.updateState(pcc.idx, state))
}
type pomeriumClientConnData struct {
mu sync.Mutex
states []resolver.State
}
func (pccd *pomeriumClientConnData) updateState(idx int, state resolver.State) resolver.State {
pccd.mu.Lock()
defer pccd.mu.Unlock()
pccd.states[idx] = state
merged := resolver.State{}
for _, s := range pccd.states {
merged.Addresses = append(merged.Addresses, s.Addresses...)
merged.ServiceConfig = s.ServiceConfig
merged.Attributes = s.Attributes
}
return merged
}
func parseTarget(raw string) resolver.Target {
target := resolver.Target{
Scheme: resolver.GetDefaultScheme(),
}
if idx := strings.Index(raw, "://"); idx >= 0 {
target.Scheme = raw[:idx]
raw = raw[idx+3:]
}
if idx := strings.Index(raw, "/"); idx >= 0 {
target.Authority = raw[:idx]
raw = raw[idx+1:]
}
target.Endpoint = raw
return target
}