mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-29 07:49:14 +01:00
[management] optimize posture cache (#8366)
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package nmdata
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/netbirdio/netbird/shared/management/certposture"
|
||||
@@ -9,8 +11,21 @@ import (
|
||||
// CertificateCheck is the slim twin of posture.CertificateCheck.
|
||||
type CertificateCheck struct {
|
||||
CACertificates []string
|
||||
|
||||
rootsOnce sync.Once
|
||||
roots *x509.CertPool
|
||||
rootsErr error
|
||||
}
|
||||
|
||||
func (c *CertificateCheck) check(peer *Peer) (bool, error) {
|
||||
return certposture.AnyChainMatchesCAs(peer.Meta.Certificates, c.CACertificates, time.Now()), nil
|
||||
if len(peer.Meta.Certificates) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
c.rootsOnce.Do(func() {
|
||||
c.roots, c.rootsErr = certposture.ParseCAs(c.CACertificates)
|
||||
})
|
||||
if c.rootsErr != nil {
|
||||
return false, c.rootsErr
|
||||
}
|
||||
return certposture.AnyChainMatchesPool(peer.Meta.Certificates, c.roots, time.Now()), nil
|
||||
}
|
||||
|
||||
@@ -26,3 +26,27 @@ func TestCertificateCheck_Check(t *testing.T) {
|
||||
otherOnly := bundle(ChecksDefinition{CertificateCheck: &CertificateCheck{CACertificates: []string{otherCA.PEM}}})
|
||||
assert.False(t, otherOnly[0].Passes(with))
|
||||
}
|
||||
|
||||
func TestCertificateCheck_ReusesParsedCAs(t *testing.T) {
|
||||
ca := certtest.NewCA(t, "corp-root")
|
||||
chain := certposture.EncodeChainPEM([]*x509.Certificate{ca.Issue(t, certtest.ECDSAKey(t), "device")})
|
||||
with := &Peer{Meta: PeerSystemMeta{Certificates: []string{chain}}}
|
||||
|
||||
check := &CertificateCheck{CACertificates: []string{ca.PEM}}
|
||||
for range 3 {
|
||||
valid, err := check.check(with)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, valid)
|
||||
}
|
||||
|
||||
invalid := &CertificateCheck{CACertificates: []string{"not a pem"}}
|
||||
for range 2 {
|
||||
valid, err := invalid.check(with)
|
||||
assert.ErrorIs(t, err, certposture.ErrNoCertificateInPEM)
|
||||
assert.False(t, valid)
|
||||
}
|
||||
|
||||
valid, err := invalid.check(&Peer{})
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, valid, "a peer without certificates fails before the CAs are parsed")
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package nmdata
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/go-version"
|
||||
)
|
||||
@@ -9,27 +10,26 @@ import (
|
||||
// NBVersionCheck is the slim twin of posture.NBVersionCheck.
|
||||
type NBVersionCheck struct {
|
||||
MinVersion string
|
||||
|
||||
constraintOnce sync.Once
|
||||
constraint version.Constraints
|
||||
constraintErr error
|
||||
}
|
||||
|
||||
func (n *NBVersionCheck) check(peer *Peer) (bool, error) {
|
||||
return meetsMinVersion(n.MinVersion, peer.Meta.WtVersion)
|
||||
}
|
||||
|
||||
func meetsMinVersion(minVer, peerVer string) (bool, error) {
|
||||
peerVer = sanitizeVersion(peerVer)
|
||||
minVer = sanitizeVersion(minVer)
|
||||
|
||||
peerNBVer, err := version.NewVersion(peerVer)
|
||||
peerNBVer, err := version.NewVersion(sanitizeVersion(peer.Meta.WtVersion))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
constraints, err := version.NewConstraint(">= " + minVer)
|
||||
if err != nil {
|
||||
return false, err
|
||||
n.constraintOnce.Do(func() {
|
||||
n.constraint, n.constraintErr = version.NewConstraint(">= " + sanitizeVersion(n.MinVersion))
|
||||
})
|
||||
if n.constraintErr != nil {
|
||||
return false, n.constraintErr
|
||||
}
|
||||
|
||||
return constraints.Check(peerNBVer), nil
|
||||
return n.constraint.Check(peerNBVer), nil
|
||||
}
|
||||
|
||||
func sanitizeVersion(v string) string {
|
||||
|
||||
Reference in New Issue
Block a user