diff --git a/cmd/clairctl/README.md b/cmd/clairctl/README.md index 56c3f4ac..ade76769 100644 --- a/cmd/clairctl/README.md +++ b/cmd/clairctl/README.md @@ -49,7 +49,6 @@ clair: port: 6060 healthPort: 6061 uri: http://clair - priority: Low report: path: ./reports format: html diff --git a/cmd/clairctl/clair/analyze.go b/cmd/clairctl/clair/analyze.go index 96596fc1..972f668a 100644 --- a/cmd/clairctl/clair/analyze.go +++ b/cmd/clairctl/clair/analyze.go @@ -13,7 +13,6 @@ import ( func Analyze(id string) (v1.LayerEnvelope, error) { lURI := fmt.Sprintf("%v/layers/%v?vulnerabilities", uri, id) - // lURI := fmt.Sprintf("%v/layers/%v/vulnerabilities?minimumPriority=%v", uri, id, priority) response, err := http.Get(lURI) if err != nil { return v1.LayerEnvelope{}, fmt.Errorf("analysing layer %v: %v", id, err) diff --git a/cmd/clairctl/clair/clair.go b/cmd/clairctl/clair/clair.go index 6ea0c732..a1166aba 100644 --- a/cmd/clairctl/clair/clair.go +++ b/cmd/clairctl/clair/clair.go @@ -1,18 +1,17 @@ package clair import ( + "math" + "sort" "strconv" "strings" - "math" - "sort" "github.com/coreos/clair/api/v1" - "github.com/spf13/viper" "github.com/coreos/clair/cmd/clairctl/xstrings" + "github.com/spf13/viper" ) var uri string -var priority string var healthPort int //Report Reporting Config value @@ -20,27 +19,27 @@ var Report ReportConfig //VulnerabiliesCounts Total count of vulnerabilities type VulnerabiliesCounts struct { - Total int - High int - Medium int - Low int + Total int + High int + Medium int + Low int Negligible int } //RelativeCount get the percentage of vulnerabilities of a severity -func (vulnerabilityCount VulnerabiliesCounts) RelativeCount(severity string) float64 { - var count int - - switch severity { - case "High": - count = vulnerabilityCount.High - case "Medium": - count = vulnerabilityCount.Medium - case "Low": - count = vulnerabilityCount.Low - } - - return math.Ceil(float64(count) / float64(vulnerabilityCount.Total) * 100 * 100) / 100 +func (vulnerabilityCount VulnerabiliesCounts) RelativeCount(severity string) float64 { + var count int + + switch severity { + case "High": + count = vulnerabilityCount.High + case "Medium": + count = vulnerabilityCount.Medium + case "Low": + count = vulnerabilityCount.Low + } + + return math.Ceil(float64(count)/float64(vulnerabilityCount.Total)*100*100) / 100 } //ImageAnalysis Full image analysis @@ -70,32 +69,32 @@ func (imageAnalysis ImageAnalysis) CountVulnerabilities(l v1.Layer) int { // CountAllVulnerabilities Total count of vulnerabilities func (imageAnalysis ImageAnalysis) CountAllVulnerabilities() VulnerabiliesCounts { - var result VulnerabiliesCounts; - result.Total = 0 - result.High = 0 - result.Medium = 0 - result.Low = 0 + var result VulnerabiliesCounts + result.Total = 0 + result.High = 0 + result.Medium = 0 + result.Low = 0 result.Negligible = 0 - - for _, l := range imageAnalysis.Layers { - for _, f := range l.Layer.Features { - result.Total += len(f.Vulnerabilities) - for _, v := range f.Vulnerabilities { - switch v.Severity { - case "High": - result.High++ - case "Medium": - result.Medium++ - case "Low": - result.Low++ + + for _, l := range imageAnalysis.Layers { + for _, f := range l.Layer.Features { + result.Total += len(f.Vulnerabilities) + for _, v := range f.Vulnerabilities { + switch v.Severity { + case "High": + result.High++ + case "Medium": + result.Medium++ + case "Low": + result.Low++ case "Negligible": result.Negligible++ - } - } - } - } - - return result; + } + } + } + } + + return result } // Vulnerability : A vulnerability inteface @@ -104,87 +103,87 @@ type Vulnerability struct { } // Weight get the weight of the vulnerability according to its Severity -func (v Vulnerability) Weight() int { +func (v Vulnerability) Weight() int { weight := 0 - + switch v.Severity { - case "High": - weight = 4 - case "Medium": - weight = 3 - case "Low": - weight = 2 - case "Negligible": - weight = 1 - } - + case "High": + weight = 4 + case "Medium": + weight = 3 + case "Low": + weight = 2 + case "Negligible": + weight = 1 + } + return weight } // Layer : A layer inteface type Layer struct { - Name string - Path string + Name string + Path string Namespace string - Features []Feature + Features []Feature } // Feature : A feature inteface type Feature struct { - Name string - Version string + Name string + Version string Vulnerabilities []Vulnerability } // Status give the healthy / unhealthy statut of a feature -func (feature Feature) Status() bool { - return len(feature.Vulnerabilities) == 0; +func (feature Feature) Status() bool { + return len(feature.Vulnerabilities) == 0 } // Weight git the weight of a featrure according to its vulnerabilities func (feature Feature) Weight() int { weight := 0 - + for _, v := range feature.Vulnerabilities { weight += v.Weight() } - + return weight } // VulnerabilitiesBySeverity sorting vulnerabilities by severity type VulnerabilitiesBySeverity []Vulnerability -func (a VulnerabilitiesBySeverity) Len() int { return len(a) } +func (a VulnerabilitiesBySeverity) Len() int { return len(a) } func (a VulnerabilitiesBySeverity) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a VulnerabilitiesBySeverity) Less(i, j int) bool { +func (a VulnerabilitiesBySeverity) Less(i, j int) bool { return a[i].Weight() > a[j].Weight() } // LayerByVulnerabilities sorting of layers by global vulnerability type LayerByVulnerabilities []Layer -func (a LayerByVulnerabilities) Len() int { return len(a) } +func (a LayerByVulnerabilities) Len() int { return len(a) } func (a LayerByVulnerabilities) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a LayerByVulnerabilities) Less(i, j int) bool { firstVulnerabilities := 0 secondVulnerabilities := 0 - + for _, l := range a[i].Features { firstVulnerabilities = firstVulnerabilities + l.Weight() } - - for _ , l := range a[j].Features { + + for _, l := range a[j].Features { secondVulnerabilities = secondVulnerabilities + l.Weight() } - + return firstVulnerabilities > secondVulnerabilities } // FeatureByVulnerabilities sorting off features by vulnerabilities type FeatureByVulnerabilities []Feature -func (a FeatureByVulnerabilities) Len() int { return len(a) } +func (a FeatureByVulnerabilities) Len() int { return len(a) } func (a FeatureByVulnerabilities) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a FeatureByVulnerabilities) Less(i, j int) bool { @@ -194,13 +193,13 @@ func (a FeatureByVulnerabilities) Less(i, j int) bool { // SortLayers give layers ordered by vulnerability algorithm func (imageAnalysis ImageAnalysis) SortLayers() []Layer { layers := []Layer{} - + for _, l := range imageAnalysis.Layers { features := []Feature{} - + for _, f := range l.Layer.Features { vulnerabilities := []Vulnerability{} - + for _, v := range f.Vulnerabilities { nv := Vulnerability{ Name: v.Name, @@ -210,40 +209,40 @@ func (imageAnalysis ImageAnalysis) SortLayers() []Layer { Layer: l.Layer.Name, Link: v.Link, } - - vulnerabilities = append(vulnerabilities, nv); + + vulnerabilities = append(vulnerabilities, nv) } - + sort.Sort(VulnerabilitiesBySeverity(vulnerabilities)) - + nf := Feature{ - Name: f.Name, - Version: f.Version, + Name: f.Name, + Version: f.Version, Vulnerabilities: vulnerabilities, } - - features = append(features, nf); + + features = append(features, nf) } - + sort.Sort(FeatureByVulnerabilities(features)) - + nl := Layer{ - Name: l.Layer.Name, - Path: l.Layer.Path, + Name: l.Layer.Name, + Path: l.Layer.Path, Features: features, } - layers = append(layers, nl); + layers = append(layers, nl) } - - sort.Sort(LayerByVulnerabilities(layers)); - - return layers; + + sort.Sort(LayerByVulnerabilities(layers)) + + return layers } // SortVulnerabilities get all vulnerabilities sorted by Severity func (imageAnalysis ImageAnalysis) SortVulnerabilities() []Vulnerability { vulnerabilities := []Vulnerability{} - + // there should be a better method, but I don't know how to easlily concert []v1.Vulnerability to [Vulnerability] for _, l := range imageAnalysis.Layers { for _, f := range l.Layer.Features { @@ -255,13 +254,13 @@ func (imageAnalysis ImageAnalysis) SortVulnerabilities() []Vulnerability { Description: v.Description, Layer: l.Layer.Name, } - + vulnerabilities = append(vulnerabilities, nv) } } } - - sort.Sort(VulnerabilitiesBySeverity(vulnerabilities)); + + sort.Sort(VulnerabilitiesBySeverity(vulnerabilities)) return vulnerabilities } @@ -282,7 +281,6 @@ func fmtURI(u string, port int) { //Config configure Clair from configFile func Config() { fmtURI(viper.GetString("clair.uri"), viper.GetInt("clair.port")) - priority = viper.GetString("clair.priority") healthPort = viper.GetInt("clair.healthPort") Report.Path = viper.GetString("clair.report.path") Report.Format = viper.GetString("clair.report.format") diff --git a/cmd/clairctl/clairctl.yml.default b/cmd/clairctl/clairctl.yml.default index 743c73e3..7f7cf532 100644 --- a/cmd/clairctl/clairctl.yml.default +++ b/cmd/clairctl/clairctl.yml.default @@ -2,7 +2,6 @@ clair: port: 6060 healthPort: 6061 uri: http://clair - priority: Low report: path: ./reports format: html diff --git a/cmd/clairctl/cmd/analyze.go b/cmd/clairctl/cmd/analyze.go index 44f4cb9c..39345bcf 100644 --- a/cmd/clairctl/cmd/analyze.go +++ b/cmd/clairctl/cmd/analyze.go @@ -10,7 +10,6 @@ import ( "github.com/coreos/clair/cmd/clairctl/config" "github.com/coreos/clair/cmd/clairctl/docker" "github.com/spf13/cobra" - "github.com/spf13/viper" ) const analyzeTplt = ` @@ -77,6 +76,4 @@ func analyze(imageName string) clair.ImageAnalysis { func init() { RootCmd.AddCommand(analyzeCmd) analyzeCmd.Flags().BoolVarP(&docker.IsLocal, "local", "l", false, "Use local images") - analyzeCmd.Flags().StringP("priority", "p", "Low", "Vulnerabilities priority [Low, Medium, High, Critical]") - viper.BindPFlag("clair.priority", analyzeCmd.Flags().Lookup("priority")) } diff --git a/cmd/clairctl/config/config.go b/cmd/clairctl/config/config.go index aa7de44a..75bf3d29 100644 --- a/cmd/clairctl/config/config.go +++ b/cmd/clairctl/config/config.go @@ -27,7 +27,7 @@ type reportConfig struct { Path, Format string } type clairConfig struct { - URI, Priority string + URI string Port, HealthPort int Report reportConfig } @@ -81,9 +81,7 @@ func Init(cfgFile string, logLevel string) { if viper.Get("clair.healthPort") == nil { viper.Set("clair.healthPort", "6061") } - if viper.Get("clair.priority") == nil { - viper.Set("clair.priority", "Low") - } + if viper.Get("clair.report.path") == nil { viper.Set("clair.report.path", "reports") } @@ -111,7 +109,6 @@ func values() config { URI: viper.GetString("clair.uri"), Port: viper.GetInt("clair.port"), HealthPort: viper.GetInt("clair.healthPort"), - Priority: viper.GetString("clair.priority"), Report: reportConfig{ Path: viper.GetString("clair.report.path"), Format: viper.GetString("clair.report.format"), diff --git a/cmd/clairctl/config/config_test.go b/cmd/clairctl/config/config_test.go index e0429ce1..8fb02b8c 100644 --- a/cmd/clairctl/config/config_test.go +++ b/cmd/clairctl/config/config_test.go @@ -14,7 +14,6 @@ import ( const defaultValues = ` clair: uri: http://localhost - priority: Low port: 6060 healthport: 6061 report: @@ -31,7 +30,6 @@ clairctl: const customValues = ` clair: uri: http://clair - priority: High port: 6061 healthport: 6062 report: diff --git a/cmd/clairctl/contrib/.hyperclair.yml b/cmd/clairctl/contrib/.hyperclair.yml index 743c73e3..7f7cf532 100644 --- a/cmd/clairctl/contrib/.hyperclair.yml +++ b/cmd/clairctl/contrib/.hyperclair.yml @@ -2,7 +2,6 @@ clair: port: 6060 healthPort: 6061 uri: http://clair - priority: Low report: path: ./reports format: html