You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
consul/command/intention/finder/finder.go

63 lines
1.6 KiB

package finder
import (
"strings"
"sync"
"github.com/hashicorp/consul/api"
)
// Finder finds intentions by a src/dst exact match. There is currently
// no direct API to do this so this struct downloads all intentions and
// caches them once, and searches in-memory for this. For now this works since
// even with a very large number of intentions, the size of the data gzipped
// over HTTP will be relatively small.
type Finder struct {
// Client is the API client to use for any requests.
Client *api.Client
lock sync.Mutex
ixns []*api.Intention // cached list of intentions
}
// Find finds the intention that matches the given src and dst. This will
// return nil when the result is not found.
func (f *Finder) Find(src, dst string) (*api.Intention, error) {
src = StripDefaultNS(src)
dst = StripDefaultNS(dst)
f.lock.Lock()
defer f.lock.Unlock()
// If the list of ixns is nil, then we haven't fetched yet, so fetch
if f.ixns == nil {
ixns, _, err := f.Client.Connect().Intentions(nil)
if err != nil {
return nil, err
}
f.ixns = ixns
}
// Go through the intentions and find an exact match
for _, ixn := range f.ixns {
if ixn.SourceString() == src && ixn.DestinationString() == dst {
return ixn, nil
}
}
return nil, nil
}
// StripDefaultNS strips the default namespace from an argument. For now,
// the API and lookups strip this value from string output so we strip it.
func StripDefaultNS(v string) string {
if idx := strings.IndexByte(v, '/'); idx > 0 {
if v[:idx] == api.IntentionDefaultNamespace {
return v[:idx+1]
}
}
return v
}