replace priority to severity

This commit is contained in:
jgsqware 2016-05-17 18:36:51 +02:00
parent edd36db8dc
commit dd970f8b06
8 changed files with 98 additions and 112 deletions

View File

@ -49,7 +49,6 @@ clair:
port: 6060 port: 6060
healthPort: 6061 healthPort: 6061
uri: http://clair uri: http://clair
priority: Low
report: report:
path: ./reports path: ./reports
format: html format: html

View File

@ -13,7 +13,6 @@ import (
func Analyze(id string) (v1.LayerEnvelope, error) { func Analyze(id string) (v1.LayerEnvelope, error) {
lURI := fmt.Sprintf("%v/layers/%v?vulnerabilities", uri, id) 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) response, err := http.Get(lURI)
if err != nil { if err != nil {
return v1.LayerEnvelope{}, fmt.Errorf("analysing layer %v: %v", id, err) return v1.LayerEnvelope{}, fmt.Errorf("analysing layer %v: %v", id, err)

View File

@ -1,18 +1,17 @@
package clair package clair
import ( import (
"math"
"sort"
"strconv" "strconv"
"strings" "strings"
"math"
"sort"
"github.com/coreos/clair/api/v1" "github.com/coreos/clair/api/v1"
"github.com/spf13/viper"
"github.com/coreos/clair/cmd/clairctl/xstrings" "github.com/coreos/clair/cmd/clairctl/xstrings"
"github.com/spf13/viper"
) )
var uri string var uri string
var priority string
var healthPort int var healthPort int
//Report Reporting Config value //Report Reporting Config value
@ -20,27 +19,27 @@ var Report ReportConfig
//VulnerabiliesCounts Total count of vulnerabilities //VulnerabiliesCounts Total count of vulnerabilities
type VulnerabiliesCounts struct { type VulnerabiliesCounts struct {
Total int Total int
High int High int
Medium int Medium int
Low int Low int
Negligible int Negligible int
} }
//RelativeCount get the percentage of vulnerabilities of a severity //RelativeCount get the percentage of vulnerabilities of a severity
func (vulnerabilityCount VulnerabiliesCounts) RelativeCount(severity string) float64 { func (vulnerabilityCount VulnerabiliesCounts) RelativeCount(severity string) float64 {
var count int var count int
switch severity { switch severity {
case "High": case "High":
count = vulnerabilityCount.High count = vulnerabilityCount.High
case "Medium": case "Medium":
count = vulnerabilityCount.Medium count = vulnerabilityCount.Medium
case "Low": case "Low":
count = vulnerabilityCount.Low count = vulnerabilityCount.Low
} }
return math.Ceil(float64(count) / float64(vulnerabilityCount.Total) * 100 * 100) / 100 return math.Ceil(float64(count)/float64(vulnerabilityCount.Total)*100*100) / 100
} }
//ImageAnalysis Full image analysis //ImageAnalysis Full image analysis
@ -70,32 +69,32 @@ func (imageAnalysis ImageAnalysis) CountVulnerabilities(l v1.Layer) int {
// CountAllVulnerabilities Total count of vulnerabilities // CountAllVulnerabilities Total count of vulnerabilities
func (imageAnalysis ImageAnalysis) CountAllVulnerabilities() VulnerabiliesCounts { func (imageAnalysis ImageAnalysis) CountAllVulnerabilities() VulnerabiliesCounts {
var result VulnerabiliesCounts; var result VulnerabiliesCounts
result.Total = 0 result.Total = 0
result.High = 0 result.High = 0
result.Medium = 0 result.Medium = 0
result.Low = 0 result.Low = 0
result.Negligible = 0 result.Negligible = 0
for _, l := range imageAnalysis.Layers { for _, l := range imageAnalysis.Layers {
for _, f := range l.Layer.Features { for _, f := range l.Layer.Features {
result.Total += len(f.Vulnerabilities) result.Total += len(f.Vulnerabilities)
for _, v := range f.Vulnerabilities { for _, v := range f.Vulnerabilities {
switch v.Severity { switch v.Severity {
case "High": case "High":
result.High++ result.High++
case "Medium": case "Medium":
result.Medium++ result.Medium++
case "Low": case "Low":
result.Low++ result.Low++
case "Negligible": case "Negligible":
result.Negligible++ result.Negligible++
} }
} }
} }
} }
return result; return result
} }
// Vulnerability : A vulnerability inteface // Vulnerability : A vulnerability inteface
@ -104,87 +103,87 @@ type Vulnerability struct {
} }
// Weight get the weight of the vulnerability according to its Severity // Weight get the weight of the vulnerability according to its Severity
func (v Vulnerability) Weight() int { func (v Vulnerability) Weight() int {
weight := 0 weight := 0
switch v.Severity { switch v.Severity {
case "High": case "High":
weight = 4 weight = 4
case "Medium": case "Medium":
weight = 3 weight = 3
case "Low": case "Low":
weight = 2 weight = 2
case "Negligible": case "Negligible":
weight = 1 weight = 1
} }
return weight return weight
} }
// Layer : A layer inteface // Layer : A layer inteface
type Layer struct { type Layer struct {
Name string Name string
Path string Path string
Namespace string Namespace string
Features []Feature Features []Feature
} }
// Feature : A feature inteface // Feature : A feature inteface
type Feature struct { type Feature struct {
Name string Name string
Version string Version string
Vulnerabilities []Vulnerability Vulnerabilities []Vulnerability
} }
// Status give the healthy / unhealthy statut of a feature // Status give the healthy / unhealthy statut of a feature
func (feature Feature) Status() bool { func (feature Feature) Status() bool {
return len(feature.Vulnerabilities) == 0; return len(feature.Vulnerabilities) == 0
} }
// Weight git the weight of a featrure according to its vulnerabilities // Weight git the weight of a featrure according to its vulnerabilities
func (feature Feature) Weight() int { func (feature Feature) Weight() int {
weight := 0 weight := 0
for _, v := range feature.Vulnerabilities { for _, v := range feature.Vulnerabilities {
weight += v.Weight() weight += v.Weight()
} }
return weight return weight
} }
// VulnerabilitiesBySeverity sorting vulnerabilities by severity // VulnerabilitiesBySeverity sorting vulnerabilities by severity
type VulnerabilitiesBySeverity []Vulnerability 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) 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() return a[i].Weight() > a[j].Weight()
} }
// LayerByVulnerabilities sorting of layers by global vulnerability // LayerByVulnerabilities sorting of layers by global vulnerability
type LayerByVulnerabilities []Layer 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) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a LayerByVulnerabilities) Less(i, j int) bool { func (a LayerByVulnerabilities) Less(i, j int) bool {
firstVulnerabilities := 0 firstVulnerabilities := 0
secondVulnerabilities := 0 secondVulnerabilities := 0
for _, l := range a[i].Features { for _, l := range a[i].Features {
firstVulnerabilities = firstVulnerabilities + l.Weight() firstVulnerabilities = firstVulnerabilities + l.Weight()
} }
for _ , l := range a[j].Features { for _, l := range a[j].Features {
secondVulnerabilities = secondVulnerabilities + l.Weight() secondVulnerabilities = secondVulnerabilities + l.Weight()
} }
return firstVulnerabilities > secondVulnerabilities return firstVulnerabilities > secondVulnerabilities
} }
// FeatureByVulnerabilities sorting off features by vulnerabilities // FeatureByVulnerabilities sorting off features by vulnerabilities
type FeatureByVulnerabilities []Feature 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) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a FeatureByVulnerabilities) Less(i, j int) bool { 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 // SortLayers give layers ordered by vulnerability algorithm
func (imageAnalysis ImageAnalysis) SortLayers() []Layer { func (imageAnalysis ImageAnalysis) SortLayers() []Layer {
layers := []Layer{} layers := []Layer{}
for _, l := range imageAnalysis.Layers { for _, l := range imageAnalysis.Layers {
features := []Feature{} features := []Feature{}
for _, f := range l.Layer.Features { for _, f := range l.Layer.Features {
vulnerabilities := []Vulnerability{} vulnerabilities := []Vulnerability{}
for _, v := range f.Vulnerabilities { for _, v := range f.Vulnerabilities {
nv := Vulnerability{ nv := Vulnerability{
Name: v.Name, Name: v.Name,
@ -210,40 +209,40 @@ func (imageAnalysis ImageAnalysis) SortLayers() []Layer {
Layer: l.Layer.Name, Layer: l.Layer.Name,
Link: v.Link, Link: v.Link,
} }
vulnerabilities = append(vulnerabilities, nv); vulnerabilities = append(vulnerabilities, nv)
} }
sort.Sort(VulnerabilitiesBySeverity(vulnerabilities)) sort.Sort(VulnerabilitiesBySeverity(vulnerabilities))
nf := Feature{ nf := Feature{
Name: f.Name, Name: f.Name,
Version: f.Version, Version: f.Version,
Vulnerabilities: vulnerabilities, Vulnerabilities: vulnerabilities,
} }
features = append(features, nf); features = append(features, nf)
} }
sort.Sort(FeatureByVulnerabilities(features)) sort.Sort(FeatureByVulnerabilities(features))
nl := Layer{ nl := Layer{
Name: l.Layer.Name, Name: l.Layer.Name,
Path: l.Layer.Path, Path: l.Layer.Path,
Features: features, Features: features,
} }
layers = append(layers, nl); layers = append(layers, nl)
} }
sort.Sort(LayerByVulnerabilities(layers)); sort.Sort(LayerByVulnerabilities(layers))
return layers; return layers
} }
// SortVulnerabilities get all vulnerabilities sorted by Severity // SortVulnerabilities get all vulnerabilities sorted by Severity
func (imageAnalysis ImageAnalysis) SortVulnerabilities() []Vulnerability { func (imageAnalysis ImageAnalysis) SortVulnerabilities() []Vulnerability {
vulnerabilities := []Vulnerability{} vulnerabilities := []Vulnerability{}
// there should be a better method, but I don't know how to easlily concert []v1.Vulnerability to [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 _, l := range imageAnalysis.Layers {
for _, f := range l.Layer.Features { for _, f := range l.Layer.Features {
@ -255,13 +254,13 @@ func (imageAnalysis ImageAnalysis) SortVulnerabilities() []Vulnerability {
Description: v.Description, Description: v.Description,
Layer: l.Layer.Name, Layer: l.Layer.Name,
} }
vulnerabilities = append(vulnerabilities, nv) vulnerabilities = append(vulnerabilities, nv)
} }
} }
} }
sort.Sort(VulnerabilitiesBySeverity(vulnerabilities)); sort.Sort(VulnerabilitiesBySeverity(vulnerabilities))
return vulnerabilities return vulnerabilities
} }
@ -282,7 +281,6 @@ func fmtURI(u string, port int) {
//Config configure Clair from configFile //Config configure Clair from configFile
func Config() { func Config() {
fmtURI(viper.GetString("clair.uri"), viper.GetInt("clair.port")) fmtURI(viper.GetString("clair.uri"), viper.GetInt("clair.port"))
priority = viper.GetString("clair.priority")
healthPort = viper.GetInt("clair.healthPort") healthPort = viper.GetInt("clair.healthPort")
Report.Path = viper.GetString("clair.report.path") Report.Path = viper.GetString("clair.report.path")
Report.Format = viper.GetString("clair.report.format") Report.Format = viper.GetString("clair.report.format")

View File

@ -2,7 +2,6 @@ clair:
port: 6060 port: 6060
healthPort: 6061 healthPort: 6061
uri: http://clair uri: http://clair
priority: Low
report: report:
path: ./reports path: ./reports
format: html format: html

View File

@ -10,7 +10,6 @@ import (
"github.com/coreos/clair/cmd/clairctl/config" "github.com/coreos/clair/cmd/clairctl/config"
"github.com/coreos/clair/cmd/clairctl/docker" "github.com/coreos/clair/cmd/clairctl/docker"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
) )
const analyzeTplt = ` const analyzeTplt = `
@ -77,6 +76,4 @@ func analyze(imageName string) clair.ImageAnalysis {
func init() { func init() {
RootCmd.AddCommand(analyzeCmd) RootCmd.AddCommand(analyzeCmd)
analyzeCmd.Flags().BoolVarP(&docker.IsLocal, "local", "l", false, "Use local images") 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"))
} }

View File

@ -27,7 +27,7 @@ type reportConfig struct {
Path, Format string Path, Format string
} }
type clairConfig struct { type clairConfig struct {
URI, Priority string URI string
Port, HealthPort int Port, HealthPort int
Report reportConfig Report reportConfig
} }
@ -81,9 +81,7 @@ func Init(cfgFile string, logLevel string) {
if viper.Get("clair.healthPort") == nil { if viper.Get("clair.healthPort") == nil {
viper.Set("clair.healthPort", "6061") viper.Set("clair.healthPort", "6061")
} }
if viper.Get("clair.priority") == nil {
viper.Set("clair.priority", "Low")
}
if viper.Get("clair.report.path") == nil { if viper.Get("clair.report.path") == nil {
viper.Set("clair.report.path", "reports") viper.Set("clair.report.path", "reports")
} }
@ -111,7 +109,6 @@ func values() config {
URI: viper.GetString("clair.uri"), URI: viper.GetString("clair.uri"),
Port: viper.GetInt("clair.port"), Port: viper.GetInt("clair.port"),
HealthPort: viper.GetInt("clair.healthPort"), HealthPort: viper.GetInt("clair.healthPort"),
Priority: viper.GetString("clair.priority"),
Report: reportConfig{ Report: reportConfig{
Path: viper.GetString("clair.report.path"), Path: viper.GetString("clair.report.path"),
Format: viper.GetString("clair.report.format"), Format: viper.GetString("clair.report.format"),

View File

@ -14,7 +14,6 @@ import (
const defaultValues = ` const defaultValues = `
clair: clair:
uri: http://localhost uri: http://localhost
priority: Low
port: 6060 port: 6060
healthport: 6061 healthport: 6061
report: report:
@ -31,7 +30,6 @@ clairctl:
const customValues = ` const customValues = `
clair: clair:
uri: http://clair uri: http://clair
priority: High
port: 6061 port: 6061
healthport: 6062 healthport: 6062
report: report:

View File

@ -2,7 +2,6 @@ clair:
port: 6060 port: 6060
healthPort: 6061 healthPort: 6061
uri: http://clair uri: http://clair
priority: Low
report: report:
path: ./reports path: ./reports
format: html format: html