Skip to content

Commit

Permalink
🐛 report asset errors (#3152)
Browse files Browse the repository at this point in the history
  • Loading branch information
chris-rock authored Jan 30, 2024
1 parent 8cb8985 commit cbb3ae2
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 8 deletions.
4 changes: 4 additions & 0 deletions apps/cnquery/cmd/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ var scanCmdRun = func(cmd *cobra.Command, runtime *providers.Runtime, cliRes *pl
}

printReports(report, conf, cmd)

if report != nil && len(report.Errors) > 0 {
os.Exit(1)
}
}

// helper method to retrieve the list of query packs for autocomplete
Expand Down
42 changes: 34 additions & 8 deletions explorer/scan/local_scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ type assetWithRuntime struct {
runtime *providers.Runtime
}

type assetWithError struct {
asset *inventory.Asset
err error
}

type LocalScanner struct {
fetcher *fetcher
upstream *upstream.UpstreamConfig
Expand Down Expand Up @@ -194,6 +199,7 @@ func (s *LocalScanner) distributeJob(job *Job, ctx context.Context, upstream *up
var assets []*assetWithRuntime
// note: asset candidate runtimes are the runtime that discovered them
var assetCandidates []*assetWithRuntime
var assetErrors []*assetWithError

// we connect and perform discovery for each asset in the job inventory
for i := range assetList {
Expand All @@ -206,6 +212,10 @@ func (s *LocalScanner) distributeJob(job *Job, ctx context.Context, upstream *up
runtime, err := providers.Coordinator.RuntimeFor(asset, providers.DefaultRuntime())
if err != nil {
log.Error().Err(err).Str("asset", asset.Name).Msg("unable to create runtime for asset")
assetErrors = append(assetErrors, &assetWithError{
asset: resolvedAsset,
err: err,
})
continue
}
runtime.SetRecording(s.recording)
Expand All @@ -216,6 +226,10 @@ func (s *LocalScanner) distributeJob(job *Job, ctx context.Context, upstream *up
Upstream: upstream,
}); err != nil {
log.Error().Err(err).Msg("unable to connect to asset")
assetErrors = append(assetErrors, &assetWithError{
asset: resolvedAsset,
err: err,
})
continue
}
asset = runtime.Provider.Connection.Asset // to ensure we get all the information the connect call gave us
Expand All @@ -227,7 +241,11 @@ func (s *LocalScanner) distributeJob(job *Job, ctx context.Context, upstream *up
}
processedAssets, err := providers.ProcessAssetCandidates(runtime, runtime.Provider.Connection, upstream, "")
if err != nil {
return nil, false, err
assetErrors = append(assetErrors, &assetWithError{
asset: resolvedAsset,
err: err,
})
continue
}
for i := range processedAssets {
assetCandidates = append(assetCandidates, &assetWithRuntime{
Expand Down Expand Up @@ -300,10 +318,6 @@ func (s *LocalScanner) distributeJob(job *Job, ctx context.Context, upstream *up
})
}

if len(assets) == 0 {
return nil, false, nil
}

// if there is exactly one asset, assure that the --asset-name is used
// TODO: make it so that the --asset-name is set for the root asset only even if multiple assets are there
// This is a temporary fix that only works if there is only one asset
Expand All @@ -317,6 +331,20 @@ func (s *LocalScanner) distributeJob(job *Job, ctx context.Context, upstream *up
asset.asset.KindString = asset.asset.GetPlatform().Kind
justAssets = append(justAssets, asset.asset)
}
for _, asset := range assetErrors {
justAssets = append(justAssets, asset.asset)
}

// plan scan jobs
reporter := NewAggregateReporter(justAssets)
// if we had asset errors we want to place them into the reporter
for i := range assetErrors {
reporter.AddScanError(assetErrors[i].asset, assetErrors[i].err)
}

if len(assets) == 0 {
return reporter.Reports(), false, nil
}

// sync assets
if upstream != nil && upstream.ApiEndpoint != "" && !upstream.Incognito {
Expand Down Expand Up @@ -368,8 +396,6 @@ func (s *LocalScanner) distributeJob(job *Job, ctx context.Context, upstream *up
}
}

// plan scan jobs
reporter := NewAggregateReporter(justAssets)
// if a bundle was provided check that it matches the filter, bundles can also be downloaded
// later therefore we do not want to stop execution here
if job.Bundle != nil && job.Bundle.FilterQueryPacks(job.QueryPackFilters) {
Expand All @@ -382,7 +408,7 @@ func (s *LocalScanner) distributeJob(job *Job, ctx context.Context, upstream *up
// this shouldn't happen, but might
// it normally indicates a bug in the provider
if presentAsset, present := progressBarElements[assets[i].asset.PlatformIds[0]]; present {
return nil, false, fmt.Errorf("asset %s and %s have the same platform id %s", presentAsset, assets[i].asset.Name, assets[i].asset.PlatformIds[0])
return reporter.Reports(), false, fmt.Errorf("asset %s and %s have the same platform id %s", presentAsset, assets[i].asset.Name, assets[i].asset.PlatformIds[0])
}
progressBarElements[assets[i].asset.PlatformIds[0]] = assets[i].asset.Name
orderedKeys = append(orderedKeys, assets[i].asset.PlatformIds[0])
Expand Down

0 comments on commit cbb3ae2

Please sign in to comment.