Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
98 changes: 97 additions & 1 deletion cmd/scanner/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,83 @@ func scannerRegisterStream(ctx context.Context, client share.ControllerScanServi
return nil
}

func scannerRegisterV3(ctx context.Context, client share.ControllerScanServiceClient, data *share.ScannerRegisterData) error {
stream, err := client.ScannerRegisterV3(ctx)
if err != nil {
return err
}

defer func() {
if err = stream.CloseSend(); err != nil {
log.WithError(err).Debug("failed to close stream")
}
}()

// Send initial message with version info only; no CVEDB.
if err := stream.Send(&share.ScannerRegisterV3Request{
CVEDBVersion: data.CVEDBVersion,
CVEDBCreateTime: data.CVEDBCreateTime,
RPCServer: data.RPCServer,
RPCServerPort: data.RPCServerPort,
ID: data.ID,
}); err != nil {
return err
}

resp, err := stream.Recv()
if err != nil {
return err
}

switch resp.Action {
case share.ScannerRegisterV3Response_REGISTERED:
log.Info("V3 register: CVEDB already current, registered without upload")
return nil

case share.ScannerRegisterV3Response_SEND_CVEDB:
log.WithFields(log.Fields{"entries": len(data.CVEDB)}).Info("V3 register: controller requested CVEDB, streaming")
clone := make(map[string]*share.ScanVulnerability, len(data.CVEDB))
for k, v := range data.CVEDB {
clone[k] = v
}
for len(clone) > 0 {
count := cvedbChunkMax
if len(clone) < count {
count = len(clone)
}
chunk := make(map[string]*share.ScanVulnerability, count)
for k, v := range clone {
chunk[k] = v
delete(clone, k)
if count--; count == 0 {
break
}
}
isLast := len(clone) == 0
if err := stream.Send(&share.ScannerRegisterV3Request{
CVEDB: chunk,
CVEDBLast: isLast,
}); err != nil {
return err
}
}
resp, err = stream.Recv()
if err != nil {
return err
}
if resp.Action == share.ScannerRegisterV3Response_ERROR {
return errors.New(resp.Message)
}
log.Info("V3 register: CVEDB uploaded and registered")
return nil

case share.ScannerRegisterV3Response_ERROR:
return errors.New(resp.Message)
default:
return fmt.Errorf("unknown registration action: %v", resp.Action)
}
}

func isIgnorableScannerRegisterStreamCloseError(err error) bool {
s, ok := status.FromError(err)
if !ok || s.Code() != codes.Internal {
Expand Down Expand Up @@ -435,7 +512,9 @@ func scannerRegister(joinIP string, joinPort uint16, data *share.ScannerRegister
return errors.New("failed to connect to controller")
}

ctx, cancel := context.WithTimeout(context.Background(), time.Second*180)
// Timeout must be long enough for the CVEDB upload lock wait (up to 3 minutes)
// plus the actual upload and write time.
ctx, cancel := context.WithTimeout(context.Background(), time.Minute*10)
defer cancel()

caps, err := client.GetCaps(ctx, &share.RPCVoid{})
Expand Down Expand Up @@ -483,10 +562,27 @@ func scannerRegister(joinIP string, joinPort uint16, data *share.ScannerRegister
}
}

// Try v3 first: bidirectional stream, CVEDB only uploaded if controller needs it.
// Skip if controller explicitly does not advertise v3 support (old controller).
if caps == nil || caps.SupportScannerRegisterV3 {
if err = scannerRegisterV3(ctx, client, data); err != nil {
if s, ok := status.FromError(err); !ok || s.Code() != codes.Unimplemented {
log.WithFields(log.Fields{"error": err}).Error("V3 register failed")
return err
}
log.Info("V3 register API not supported, falling back to v2")
} else {
return nil
}
}

// Try v2: client-streaming, sends full CVEDB.
if err = scannerRegisterStream(ctx, client, data); err == nil {
return nil
}
log.Info("V2 register API not supported, falling back to v1")

// v1 fallback: unary, sends full CVEDB.
_, err = client.ScannerRegister(ctx, data)
if err != nil {
log.WithFields(log.Fields{"error": err}).Error("Failed to register")
Expand Down
30 changes: 20 additions & 10 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
module github.com/neuvector/scanner

go 1.26.2
go 1.26.4

replace k8s.io/cri-api => k8s.io/cri-api v0.25.16

replace github.com/neuvector/neuvector => ../neuvector

replace github.com/neuvector/neuvector/controller/k8sapi => ../neuvector/controller/k8sapi

require (
github.com/containerd/errdefs v1.0.0
github.com/google/go-containerregistry v0.21.6
Expand Down Expand Up @@ -62,7 +66,7 @@ require (
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/glebarez/go-sqlite v1.20.3 // indirect
github.com/glebarez/go-sqlite v1.22.0 // indirect
github.com/go-chi/chi/v5 v5.2.5 // indirect
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
github.com/go-logr/logr v1.4.3 // indirect
Expand Down Expand Up @@ -103,7 +107,7 @@ require (
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/in-toto/attestation v1.1.2 // indirect
github.com/in-toto/attestation v1.2.0 // indirect
github.com/in-toto/in-toto-golang v0.11.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 // indirect
Expand All @@ -129,15 +133,18 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/neuvector/neuvector/controller/k8sapi v0.0.0-00010101000000-000000000000 // indirect
github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 // indirect
github.com/oklog/ulid/v2 v2.1.1 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/opencontainers/runtime-spec v1.3.0 // indirect
github.com/opencontainers/selinux v1.13.1 // indirect
github.com/openvex/go-vex v0.2.8 // indirect
github.com/package-url/packageurl-go v0.1.5 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230126093431-47fa9a501578 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/sassoftware/relic v7.2.1+incompatible // indirect
github.com/secure-systems-lab/go-securesystemslib v0.10.0 // indirect
Expand Down Expand Up @@ -174,11 +181,14 @@ require (
golang.org/x/mod v0.36.0 // indirect
golang.org/x/net v0.55.0 // indirect
golang.org/x/oauth2 v0.36.0 // indirect
golang.org/x/sync v0.20.0 // indirect
golang.org/x/sys v0.45.0 // indirect
golang.org/x/sync v0.21.0 // indirect
golang.org/x/sys v0.46.0 // indirect
golang.org/x/telemetry v0.0.0-20260508192327-42602be52be6 // indirect
golang.org/x/term v0.43.0 // indirect
golang.org/x/text v0.37.0 // indirect
golang.org/x/time v0.15.0 // indirect
golang.org/x/tools v0.45.0 // indirect
golang.org/x/vuln v1.3.0 // indirect
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260316180232-0b37fe3546d5 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260316180232-0b37fe3546d5 // indirect
Expand All @@ -194,10 +204,10 @@ require (
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect
modernc.org/libc v1.22.2 // indirect
modernc.org/mathutil v1.5.0 // indirect
modernc.org/memory v1.5.0 // indirect
modernc.org/sqlite v1.20.3 // indirect
modernc.org/libc v1.37.6 // indirect
modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.7.2 // indirect
modernc.org/sqlite v1.28.0 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
Expand Down
Loading