diff --git a/clair.go b/clair.go index 255447b..7b1a4ac 100644 --- a/clair.go +++ b/clair.go @@ -76,12 +76,15 @@ func analyzeLayer(clairURL, path, layerName, parentLayerName string) { } // getVulnerabilities fetches vulnerabilities from Clair and extracts the required information -func getVulnerabilities(clairURL string, layerIds []string) []vulnerabilityInfo { +func getVulnerabilities(config scannerConfig, layerIds []string) []vulnerabilityInfo { var vulnerabilities = make([]vulnerabilityInfo, 0) //Last layer gives you all the vulnerabilities of all layers - rawVulnerabilities := fetchLayerVulnerabilities(clairURL, layerIds[len(layerIds)-1]) + rawVulnerabilities := fetchLayerVulnerabilities(config.clairURL, layerIds[len(layerIds)-1]) if len(rawVulnerabilities.Features) == 0 { - logger.Fatal("Could not fetch vulnerabilities. No features have been detected in the image. This usually means that the image isn't supported by Clair") + if config.exitWhenNoFeatures { + logger.Fatal("Could not fetch vulnerabilities. No features have been detected in the image. This usually means that the image isn't supported by Clair") + } + return nil } for _, feature := range rawVulnerabilities.Features { diff --git a/integration_test.go b/integration_test.go index 86987dd..9787b92 100644 --- a/integration_test.go +++ b/integration_test.go @@ -28,6 +28,7 @@ func TestDebian(t *testing.T) { "", "Unknown", true, + false, }) if len(unapproved) == 0 { t.Errorf("No vulnerabilities, expecting some") diff --git a/main.go b/main.go index 14a61b9..0ae69d7 100644 --- a/main.go +++ b/main.go @@ -26,6 +26,7 @@ func main() { reportAll = app.BoolOpt("all reportAll", true, "Display all vulnerabilities, even if they are approved") reportFile = app.StringOpt("r report", "", "Report output file, as JSON") imageName = app.StringArg("IMAGE", "", "Name of the Docker image to scan") + exitWhenNoFeatures = app.BoolOpt("exit-when-no-features", false, "Exit with status code 1 when no features are found for a particular image") ) app.Before = func() { @@ -51,6 +52,7 @@ func main() { *reportFile, *whitelistThreshold, *reportAll, + *exitWhenNoFeatures, }) if len(result) > 0 { os.Exit(1) diff --git a/scanner.go b/scanner.go index 468ebee..114d055 100644 --- a/scanner.go +++ b/scanner.go @@ -20,6 +20,7 @@ type scannerConfig struct { reportFile string whitelistThreshold string reportAll bool + exitWhenNoFeatures bool } // scan orchestrates the scanning process of an image @@ -37,7 +38,11 @@ func scan(config scannerConfig) []string { //Analyze the layers analyzeLayers(layerIds, config.clairURL, config.scannerIP) - vulnerabilities := getVulnerabilities(config.clairURL, layerIds) + vulnerabilities := getVulnerabilities(config, layerIds) + + if len(vulnerabilities) == 0 { + return []string{} + } //Check vulnerabilities against whitelist and report unapproved := checkForUnapprovedVulnerabilities(config.imageName, vulnerabilities, config.whitelist, config.whitelistThreshold)