[management] optimize posture cache (#8366)

This commit is contained in:
Pascal Fischer
2026-10-26 16:03:33 +01:00
committed by GitHub
parent afa6eec6a7
commit 2c68a84a97
11 changed files with 690 additions and 182 deletions
@@ -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 {