2017-06-05 14:37:29 +00:00
|
|
|
// Copyright 2017 clair authors
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package clairpb
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/coreos/clair/database"
|
|
|
|
"github.com/coreos/clair/ext/versionfmt"
|
|
|
|
)
|
|
|
|
|
2017-07-12 21:04:05 +00:00
|
|
|
// PagedVulnerableAncestriesFromDatabaseModel converts database
|
|
|
|
// PagedVulnerableAncestries to api PagedVulnerableAncestries and assigns
|
|
|
|
// indexes to ancestries.
|
|
|
|
func PagedVulnerableAncestriesFromDatabaseModel(dbVuln *database.PagedVulnerableAncestries) (*PagedVulnerableAncestries, error) {
|
|
|
|
if dbVuln == nil {
|
|
|
|
return nil, nil
|
2017-06-05 14:37:29 +00:00
|
|
|
}
|
|
|
|
|
2017-07-12 21:04:05 +00:00
|
|
|
vuln, err := VulnerabilityFromDatabaseModel(dbVuln.Vulnerability)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
next := ""
|
|
|
|
if !dbVuln.End {
|
|
|
|
next = string(dbVuln.Next)
|
2017-06-05 14:37:29 +00:00
|
|
|
}
|
|
|
|
|
2017-07-12 21:04:05 +00:00
|
|
|
vulnAncestry := PagedVulnerableAncestries{
|
|
|
|
Vulnerability: vuln,
|
|
|
|
CurrentPage: string(dbVuln.Current),
|
|
|
|
NextPage: next,
|
|
|
|
Limit: int32(dbVuln.Limit),
|
2017-06-05 14:37:29 +00:00
|
|
|
}
|
|
|
|
|
2017-07-12 21:04:05 +00:00
|
|
|
for index, ancestryName := range dbVuln.Affected {
|
|
|
|
indexedAncestry := IndexedAncestryName{
|
|
|
|
Name: ancestryName,
|
|
|
|
Index: int32(index),
|
|
|
|
}
|
|
|
|
vulnAncestry.Ancestries = append(vulnAncestry.Ancestries, &indexedAncestry)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &vulnAncestry, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// NotificationFromDatabaseModel converts database notification, old and new
|
|
|
|
// vulnerabilities' paged vulnerable ancestries to be api notification.
|
|
|
|
func NotificationFromDatabaseModel(dbNotification database.VulnerabilityNotificationWithVulnerable) (*Notification, error) {
|
|
|
|
var (
|
|
|
|
noti Notification
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
|
|
|
|
noti.Name = dbNotification.Name
|
2017-06-05 14:37:29 +00:00
|
|
|
if !dbNotification.Created.IsZero() {
|
2017-07-12 21:04:05 +00:00
|
|
|
noti.Created = fmt.Sprintf("%d", dbNotification.Created.Unix())
|
2017-06-05 14:37:29 +00:00
|
|
|
}
|
2017-07-12 21:04:05 +00:00
|
|
|
|
2017-06-05 14:37:29 +00:00
|
|
|
if !dbNotification.Notified.IsZero() {
|
2017-07-12 21:04:05 +00:00
|
|
|
noti.Notified = fmt.Sprintf("%d", dbNotification.Notified.Unix())
|
2017-06-05 14:37:29 +00:00
|
|
|
}
|
2017-07-12 21:04:05 +00:00
|
|
|
|
2017-06-05 14:37:29 +00:00
|
|
|
if !dbNotification.Deleted.IsZero() {
|
2017-07-12 21:04:05 +00:00
|
|
|
noti.Deleted = fmt.Sprintf("%d", dbNotification.Deleted.Unix())
|
|
|
|
}
|
2017-06-05 14:37:29 +00:00
|
|
|
|
2017-07-12 21:04:05 +00:00
|
|
|
noti.Old, err = PagedVulnerableAncestriesFromDatabaseModel(dbNotification.Old)
|
2017-06-05 14:37:29 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2017-07-12 21:04:05 +00:00
|
|
|
noti.New, err = PagedVulnerableAncestriesFromDatabaseModel(dbNotification.New)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return ¬i, nil
|
2017-06-05 14:37:29 +00:00
|
|
|
}
|
|
|
|
|
2017-07-12 21:04:05 +00:00
|
|
|
func VulnerabilityFromDatabaseModel(dbVuln database.Vulnerability) (*Vulnerability, error) {
|
2017-06-05 14:37:29 +00:00
|
|
|
metaString := ""
|
|
|
|
if dbVuln.Metadata != nil {
|
|
|
|
metadataByte, err := json.Marshal(dbVuln.Metadata)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
metaString = string(metadataByte)
|
|
|
|
}
|
|
|
|
|
2017-07-12 21:04:05 +00:00
|
|
|
return &Vulnerability{
|
2017-06-05 14:37:29 +00:00
|
|
|
Name: dbVuln.Name,
|
|
|
|
NamespaceName: dbVuln.Namespace.Name,
|
|
|
|
Description: dbVuln.Description,
|
|
|
|
Link: dbVuln.Link,
|
|
|
|
Severity: string(dbVuln.Severity),
|
|
|
|
Metadata: metaString,
|
2017-07-12 21:04:05 +00:00
|
|
|
}, nil
|
|
|
|
}
|
2017-06-05 14:37:29 +00:00
|
|
|
|
2017-07-12 21:04:05 +00:00
|
|
|
func VulnerabilityWithFixedInFromDatabaseModel(dbVuln database.VulnerabilityWithFixedIn) (*Vulnerability, error) {
|
|
|
|
vuln, err := VulnerabilityFromDatabaseModel(dbVuln.Vulnerability)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2017-06-05 14:37:29 +00:00
|
|
|
}
|
|
|
|
|
2017-07-12 21:04:05 +00:00
|
|
|
vuln.FixedBy = dbVuln.FixedInVersion
|
|
|
|
return vuln, nil
|
2017-06-05 14:37:29 +00:00
|
|
|
}
|
|
|
|
|
2017-07-12 21:04:05 +00:00
|
|
|
// AncestryFromDatabaseModel converts database ancestry to api ancestry.
|
|
|
|
func AncestryFromDatabaseModel(dbAncestry database.Ancestry) *Ancestry {
|
|
|
|
ancestry := &Ancestry{
|
|
|
|
Name: dbAncestry.Name,
|
2017-06-05 14:37:29 +00:00
|
|
|
}
|
2017-07-12 21:04:05 +00:00
|
|
|
for _, layer := range dbAncestry.Layers {
|
|
|
|
ancestry.Layers = append(ancestry.Layers, LayerFromDatabaseModel(layer))
|
2017-06-05 14:37:29 +00:00
|
|
|
}
|
2017-07-12 21:04:05 +00:00
|
|
|
return ancestry
|
|
|
|
}
|
2017-06-05 14:37:29 +00:00
|
|
|
|
2017-07-12 21:04:05 +00:00
|
|
|
// LayerFromDatabaseModel converts database layer to api layer.
|
|
|
|
func LayerFromDatabaseModel(dbLayer database.Layer) *Layer {
|
|
|
|
layer := Layer{Hash: dbLayer.Hash}
|
2017-06-05 14:37:29 +00:00
|
|
|
return &layer
|
|
|
|
}
|
|
|
|
|
2017-07-12 21:04:05 +00:00
|
|
|
// NamespacedFeatureFromDatabaseModel converts database namespacedFeature to api Feature.
|
|
|
|
func NamespacedFeatureFromDatabaseModel(feature database.NamespacedFeature) *Feature {
|
|
|
|
version := feature.Feature.Version
|
2017-06-05 14:37:29 +00:00
|
|
|
if version == versionfmt.MaxVersion {
|
|
|
|
version = "None"
|
|
|
|
}
|
|
|
|
|
2017-07-12 21:04:05 +00:00
|
|
|
return &Feature{
|
|
|
|
Name: feature.Feature.Name,
|
|
|
|
NamespaceName: feature.Namespace.Name,
|
|
|
|
VersionFormat: feature.Namespace.VersionFormat,
|
|
|
|
Version: version,
|
2017-06-05 14:37:29 +00:00
|
|
|
}
|
|
|
|
}
|