clair: use v3 API falling back to v2 (#127)

This commit is contained in:
Jimmy Zelinskie 2018-08-09 15:59:24 -04:00 committed by Jess Frazelle
parent 65b2c0329d
commit 18f47cd736
4 changed files with 23 additions and 16 deletions

View file

@ -42,6 +42,7 @@ func (c *Clair) PostAncestry(name string, layers []*clairpb.PostAncestryRequest_
resp, err := client.PostAncestry(context.Background(), &clairpb.PostAncestryRequest{
AncestryName: name,
Layers: layers,
Format: "Docker",
})
if err != nil {
return err

View file

@ -52,7 +52,7 @@ func (c *Clair) NewClairV3Layer(r *registry.Registry, image string, fsLayer dist
}, nil
}
func (c *Clair) getFilteredLayers(r *registry.Registry, repo, tag string) (map[int]distribution.Descriptor, error) {
func (c *Clair) getLayers(r *registry.Registry, repo, tag string, filterEmpty bool) (map[int]distribution.Descriptor, error) {
ok := true
// Get the manifest to pass to clair.
mf, err := r.ManifestV2(repo, tag)
@ -66,7 +66,9 @@ func (c *Clair) getFilteredLayers(r *registry.Registry, repo, tag string) (map[i
// Filter out the empty layers.
if ok {
for i := 0; i < len(mf.Layers); i++ {
if !IsEmptyLayer(mf.Layers[i].Digest) {
if filterEmpty && IsEmptyLayer(mf.Layers[i].Digest) {
continue
} else {
filteredLayers[len(mf.Layers)-i-1] = mf.Layers[i]
}
}
@ -80,12 +82,12 @@ func (c *Clair) getFilteredLayers(r *registry.Registry, repo, tag string) (map[i
}
for i := 0; i < len(m.FSLayers); i++ {
if !IsEmptyLayer(m.FSLayers[i].BlobSum) {
newLayer := distribution.Descriptor{
if filterEmpty && IsEmptyLayer(m.FSLayers[i].BlobSum) {
continue
} else {
filteredLayers[i] = distribution.Descriptor{
Digest: m.FSLayers[i].BlobSum,
}
filteredLayers[i] = newLayer
}
}

View file

@ -19,7 +19,7 @@ func (c *Clair) Vulnerabilities(r *registry.Registry, repo, tag string) (Vulnera
VulnsBySeverity: make(map[string][]Vulnerability),
}
filteredLayers, err := c.getFilteredLayers(r, repo, tag)
filteredLayers, err := c.getLayers(r, repo, tag, true)
if err != nil {
return report, fmt.Errorf("getting filtered layers failed: %v", err)
}
@ -83,20 +83,20 @@ func (c *Clair) VulnerabilitiesV3(r *registry.Registry, repo, tag string) (Vulne
VulnsBySeverity: make(map[string][]Vulnerability),
}
filteredLayers, err := c.getFilteredLayers(r, repo, tag)
layers, err := c.getLayers(r, repo, tag, false)
if err != nil {
return report, fmt.Errorf("getting filtered layers failed: %v", err)
}
if len(filteredLayers) == 0 {
fmt.Printf("No need to analyse image %s:%s as there is no non-emtpy layer", repo, tag)
if len(layers) == 0 {
fmt.Printf("No need to analyse image %s:%s as there is no non-empty layer", repo, tag)
return report, nil
}
clairLayers := []*clairpb.PostAncestryRequest_PostLayer{}
for i := len(filteredLayers) - 1; i >= 0; i-- {
for i := len(layers) - 1; i >= 0; i-- {
// Form the clair layer.
l, err := c.NewClairV3Layer(r, repo, filteredLayers[i])
l, err := c.NewClairV3Layer(r, repo, layers[i])
if err != nil {
return report, err
}
@ -106,12 +106,12 @@ func (c *Clair) VulnerabilitiesV3(r *registry.Registry, repo, tag string) (Vulne
}
// Post the ancestry.
if err := c.PostAncestry(filteredLayers[0].Digest.String(), clairLayers); err != nil {
if err := c.PostAncestry(layers[0].Digest.String(), clairLayers); err != nil {
return report, fmt.Errorf("posting ancestry failed: %v", err)
}
// Get the ancestry.
vl, err := c.GetAncestry(filteredLayers[0].Digest.String(), true, true)
vl, err := c.GetAncestry(layers[0].Digest.String(), true, true)
if err != nil {
return report, err
}

View file

@ -64,9 +64,13 @@ func (cmd *vulnsCommand) Run(ctx context.Context, args []string) error {
}
// Get the vulnerability report.
report, err := cr.Vulnerabilities(r, image.Path, image.Reference())
report, err := cr.VulnerabilitiesV3(r, image.Path, image.Reference())
if err != nil {
return err
// Fallback to Clair v2 API.
report, err = cr.Vulnerabilities(r, image.Path, image.Reference())
if err != nil {
return err
}
}
// Iterate over the vulnerabilities by severity list.