Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2d53f52
Introduce Inventory conversion
Maddosaurus Sep 5, 2024
db2c050
Added scanenr version (gen code), first part of conversion functions
Maddosaurus Sep 24, 2024
c92f15c
WIP: Prep for NodeScan conversion
Maddosaurus Sep 26, 2024
86662d0
WIP: ToNodeScan converter
Maddosaurus Oct 1, 2024
0af7ffd
Rebase and regen proto code
Maddosaurus Oct 7, 2024
705c630
Add tests, switch conversion to cvss_metrics
Maddosaurus Oct 7, 2024
c473a7c
Update compliance/index/v4/convert.go
Maddosaurus Oct 8, 2024
46f4cd0
Ensure converter only accesses existing vulnerabilities
Maddosaurus Oct 8, 2024
79bd060
Update generated
Maddosaurus Oct 8, 2024
50efe8a
Add updated gen node.pb.go
Maddosaurus Oct 9, 2024
e45ef15
Update compliance/index/v4/convert.go
Maddosaurus Oct 9, 2024
d29c2f5
Address review comments
Maddosaurus Oct 9, 2024
abe1215
Remove unused proto field
Maddosaurus Oct 9, 2024
d9801f7
Update generated, fix tests
Maddosaurus Oct 9, 2024
3ba7132
Move conversion package to correct location
Maddosaurus Oct 10, 2024
9776844
Wire up converter in v4 pipeline, ensure v2 pipeline skips
Maddosaurus Oct 10, 2024
f86d967
Correct NodeId, clean up merge artifacts
Maddosaurus Oct 11, 2024
c02555b
Redesign converter to add all components, not only ones with vulnerab…
Maddosaurus Oct 11, 2024
8cbaa32
Remove warning log
Maddosaurus Oct 11, 2024
420ebad
Workaround for incorrect Node labels, fill OS field in NodeScan
Maddosaurus Oct 11, 2024
e86b195
Correct CVSS, link, and severity conversions
Maddosaurus Oct 14, 2024
cd83f9f
Address feedback
Maddosaurus Oct 15, 2024
ea1b6a0
Address feedback Pt2
Maddosaurus Oct 15, 2024
c40bbd9
Change log message for getPackageVulns
Maddosaurus Oct 15, 2024
449579b
Rephrase and optimize logs
Maddosaurus Oct 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions central/graphql/resolvers/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 25 additions & 21 deletions central/sensor/service/pipeline/nodeindex/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/stackrox/rox/central/sensor/service/pipeline/reconciliation"
"github.com/stackrox/rox/generated/internalapi/central"
"github.com/stackrox/rox/pkg/centralsensor"
"github.com/stackrox/rox/pkg/features"
"github.com/stackrox/rox/pkg/logging"
"github.com/stackrox/rox/pkg/nodes/enricher"
)
Expand Down Expand Up @@ -56,7 +57,11 @@ func (p pipelineImpl) Match(msg *central.MsgFromSensor) bool {
return msg.GetEvent().GetIndexReport() != nil
}

func (p pipelineImpl) Run(ctx context.Context, clusterID string, msg *central.MsgFromSensor, _ common.MessageInjector) error {
func (p pipelineImpl) Run(ctx context.Context, _ string, msg *central.MsgFromSensor, _ common.MessageInjector) error {
if !features.ScannerV4.Enabled() {
// If Scanner V4 is disabled do not run this pipeline
return nil
}
event := msg.GetEvent()
report := event.GetIndexReport()
if report == nil {
Expand All @@ -66,37 +71,36 @@ func (p pipelineImpl) Run(ctx context.Context, clusterID string, msg *central.Ms
log.Errorf("index report from node %s has unsupported action: %q", event.GetNode().GetName(), event.GetAction())
return nil
}
log.Debugf("received node index report with %d packages from %d content sets for node %s",
len(report.GetContents().Packages), len(report.GetContents().Repositories), event.GetId())
cr := report.CloneVT()
log.Debugf("received node index report for node %s with %d packages from %d content sets",
event.GetId(), len(report.GetContents().Packages), len(report.GetContents().Repositories))
report = report.CloneVT()

// Read the node from the database, if not found we fail.
node, found, err := p.nodeDatastore.GetNode(ctx, event.GetId())
// Query storage for the node this report comes from
nodeId := event.GetId()
node, found, err := p.nodeDatastore.GetNode(ctx, nodeId)
if err != nil {
return errors.WithMessagef(err, "fetching node: %s", event.GetId())
return errors.WithMessagef(err, "failed to fetch node %s from database", nodeId)
}
if !found {
return errors.WithMessagef(err, "node does not exist: %s", event.GetId())
return errors.WithMessagef(err, "node %s not found in datastore", nodeId)
}

// Send the Node and Index Report to Scanner for enrichment
err = p.enricher.EnrichNodeWithInventory(node, nil, cr)
// Send the Node and Index Report to Scanner for enrichment. The result will be persisted in node.NodeScan
err = p.enricher.EnrichNodeWithInventory(node, nil, report)
if err != nil {
return errors.WithMessagef(err, "enriching node %s with index report", event.GetId())
return errors.WithMessagef(err, "enriching node %s with index report", nodeId)
}
log.Infof("Successfully enriched node %s with index report.", node.GetName())
log.Debugf("Successfully enriched node %s with %s report - found %d components (id: %s)",
node.GetName(), node.GetScan().GetScannerVersion().String(), len(node.GetScan().GetComponents()), nodeId)

// TODO(ROX-26089): Update the whole node in the database with the new and previous information after conversion
/*
err = p.riskManager.CalculateRiskAndUpsertNode(node)
if err != nil {
log.Error(err)
return err
}
*/
// Update the whole node in the database with the new and previous information.
err = p.riskManager.CalculateRiskAndUpsertNode(node)
if err != nil {
log.Error(err)
return err
}

return nil

}

func (p pipelineImpl) Reconcile(_ context.Context, _ string, _ *reconciliation.StoreMap) error {
Expand Down
33 changes: 25 additions & 8 deletions central/sensor/service/pipeline/nodeinventory/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import (
"github.com/stackrox/rox/central/sensor/service/pipeline"
"github.com/stackrox/rox/central/sensor/service/pipeline/reconciliation"
"github.com/stackrox/rox/generated/internalapi/central"
"github.com/stackrox/rox/generated/storage"
"github.com/stackrox/rox/pkg/centralsensor"
"github.com/stackrox/rox/pkg/features"
"github.com/stackrox/rox/pkg/logging"
"github.com/stackrox/rox/pkg/metrics"
"github.com/stackrox/rox/pkg/nodes/enricher"
Expand Down Expand Up @@ -90,6 +92,16 @@ func (p *pipelineImpl) Run(ctx context.Context, _ string, msg *central.MsgFromSe
return errors.WithMessagef(err, "node does not exist: %s", ninv.GetNodeId())
}

// Discard message if NodeScanning v4 and v2 are running in parallel - v4 scans are prioritized in that case.
// The message will be kept even if a v4 scan is already persisted for the node if the feature flag for
// Scanner v4 has been disabled. This ensures node scans are updated even if a customer falls back to Scanner v2.
if node.GetScan() != nil && node.GetScan().GetScannerVersion() == storage.NodeScan_SCANNER_V4 && features.ScannerV4.Enabled() {
// To prevent resending the inventory, still acknowledge receipt of it
sendComplianceAck(ctx, node, ninv, injector)
log.Debugf("Discarding v2 NodeScan in favor of v4 NodeScan")
return nil
}

// Call Scanner to enrich the node inventory and attach the results to the node object.
err = p.enricher.EnrichNodeWithInventory(node, ninv, nil)
if err != nil {
Expand All @@ -106,17 +118,22 @@ func (p *pipelineImpl) Run(ctx context.Context, _ string, msg *central.MsgFromSe
return err
}

if injector != nil {
reply := replyCompliance(node.GetClusterId(), ninv.GetNodeName(), central.NodeInventoryACK_ACK)
if err := injector.InjectMessage(ctx, reply); err != nil {
log.Warnf("Failed sending node-scanning-ACK to Sensor for %s: %v", nodeDatastore.NodeString(node), err)
} else {
log.Debugf("Sent node-scanning-ACK for %s", nodeDatastore.NodeString(node))
}
}
sendComplianceAck(ctx, node, ninv, injector)
return nil
}

func sendComplianceAck(ctx context.Context, node *storage.Node, ninv *storage.NodeInventory, injector common.MessageInjector) {
if injector == nil {
return
}
reply := replyCompliance(node.GetClusterId(), ninv.GetNodeName(), central.NodeInventoryACK_ACK)
if err := injector.InjectMessage(ctx, reply); err != nil {
log.Warnf("Failed sending node-scanning-ACK to Sensor for %s: %v", nodeDatastore.NodeString(node), err)
} else {
log.Debugf("Sent node-scanning-ACK for %s", nodeDatastore.NodeString(node))
}
}

func replyCompliance(clusterID, nodeName string, t central.NodeInventoryACK_Action) *central.MsgToSensor {
return &central.MsgToSensor{
Msg: &central.MsgToSensor_NodeInventoryAck{
Expand Down
12 changes: 12 additions & 0 deletions generated/api/v1/node_service.swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading