-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
database: Restructure database folder
- one pgsql data model per folder, and one table per file - one data model per file
- Loading branch information
1 parent
4fa03d1
commit d3a1e55
Showing
43 changed files
with
1,336 additions
and
1,290 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package database | ||
|
||
// Ancestry is a manifest that keeps all layers in an image in order. | ||
type Ancestry struct { | ||
// Name is a globally unique value for a set of layers. This is often the | ||
// sha256 digest of an OCI/Docker manifest. | ||
Name string `json:"name"` | ||
// By contains the processors that are used when computing the | ||
// content of this ancestry. | ||
By []Detector `json:"by"` | ||
// Layers should be ordered and i_th layer is the parent of i+1_th layer in | ||
// the slice. | ||
Layers []AncestryLayer `json:"layers"` | ||
} | ||
|
||
// Valid checks if the ancestry is compliant to spec. | ||
func (a *Ancestry) Valid() bool { | ||
if a == nil { | ||
return false | ||
} | ||
|
||
if a.Name == "" { | ||
return false | ||
} | ||
|
||
for _, d := range a.By { | ||
if !d.Valid() { | ||
return false | ||
} | ||
} | ||
|
||
for _, l := range a.Layers { | ||
if !l.Valid() { | ||
return false | ||
} | ||
} | ||
|
||
return true | ||
} | ||
|
||
// AncestryLayer is a layer with all detected namespaced features. | ||
type AncestryLayer struct { | ||
// Hash is the sha-256 tarsum on the layer's blob content. | ||
Hash string `json:"hash"` | ||
// Features are the features introduced by this layer when it was | ||
// processed. | ||
Features []AncestryFeature `json:"features"` | ||
} | ||
|
||
// Valid checks if the Ancestry Layer is compliant to the spec. | ||
func (l *AncestryLayer) Valid() bool { | ||
if l == nil { | ||
return false | ||
} | ||
|
||
if l.Hash == "" { | ||
return false | ||
} | ||
|
||
return true | ||
} | ||
|
||
// GetFeatures returns the Ancestry's features. | ||
func (l *AncestryLayer) GetFeatures() []NamespacedFeature { | ||
nsf := make([]NamespacedFeature, 0, len(l.Features)) | ||
for _, f := range l.Features { | ||
nsf = append(nsf, f.NamespacedFeature) | ||
} | ||
|
||
return nsf | ||
} | ||
|
||
// AncestryFeature is a namespaced feature with the detectors used to | ||
// find this feature. | ||
type AncestryFeature struct { | ||
NamespacedFeature `json:"namespacedFeature"` | ||
|
||
// FeatureBy is the detector that detected the feature. | ||
FeatureBy Detector `json:"featureBy"` | ||
// NamespaceBy is the detector that detected the namespace. | ||
NamespaceBy Detector `json:"namespaceBy"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package database | ||
|
||
// Feature represents a package detected in a layer but the namespace is not | ||
// determined. | ||
// | ||
// e.g. Name: Libssl1.0, Version: 1.0, VersionFormat: dpkg, Type: binary | ||
// dpkg is the version format of the installer package manager, which in this | ||
// case could be dpkg or apk. | ||
type Feature struct { | ||
Name string `json:"name"` | ||
Version string `json:"version"` | ||
VersionFormat string `json:"versionFormat"` | ||
Type FeatureType `json:"type"` | ||
} | ||
|
||
// NamespacedFeature is a feature with determined namespace and can be affected | ||
// by vulnerabilities. | ||
// | ||
// e.g. OpenSSL 1.0 dpkg Debian:7. | ||
type NamespacedFeature struct { | ||
Feature `json:"feature"` | ||
|
||
Namespace Namespace `json:"namespace"` | ||
} | ||
|
||
// AffectedNamespacedFeature is a namespaced feature affected by the | ||
// vulnerabilities with fixed-in versions for this feature. | ||
type AffectedNamespacedFeature struct { | ||
NamespacedFeature | ||
|
||
AffectedBy []VulnerabilityWithFixedIn | ||
} | ||
|
||
// VulnerabilityWithFixedIn is used for AffectedNamespacedFeature to retrieve | ||
// the affecting vulnerabilities and the fixed-in versions for the feature. | ||
type VulnerabilityWithFixedIn struct { | ||
Vulnerability | ||
|
||
FixedInVersion string | ||
} | ||
|
||
// AffectedFeature is used to determine whether a namespaced feature is affected | ||
// by a Vulnerability. Namespace and Feature Name is unique. Affected Feature is | ||
// bound to vulnerability. | ||
type AffectedFeature struct { | ||
// FeatureType determines which type of package it affects. | ||
FeatureType FeatureType | ||
Namespace Namespace | ||
FeatureName string | ||
// FixedInVersion is known next feature version that's not affected by the | ||
// vulnerability. Empty FixedInVersion means the unaffected version is | ||
// unknown. | ||
FixedInVersion string | ||
// AffectedVersion contains the version range to determine whether or not a | ||
// feature is affected. | ||
AffectedVersion string | ||
} | ||
|
||
// NullableAffectedNamespacedFeature is an affectednamespacedfeature with | ||
// whether it's found in datastore. | ||
type NullableAffectedNamespacedFeature struct { | ||
AffectedNamespacedFeature | ||
|
||
Valid bool | ||
} | ||
|
||
func NewFeature(name string, version string, versionFormat string, featureType FeatureType) *Feature { | ||
return &Feature{name, version, versionFormat, featureType} | ||
} | ||
|
||
func NewBinaryPackage(name string, version string, versionFormat string) *Feature { | ||
return &Feature{name, version, versionFormat, BinaryPackage} | ||
} | ||
|
||
func NewSourcePackage(name string, version string, versionFormat string) *Feature { | ||
return &Feature{name, version, versionFormat, SourcePackage} | ||
} | ||
|
||
func NewNamespacedFeature(namespace *Namespace, feature *Feature) *NamespacedFeature { | ||
// TODO: namespaced feature should use pointer values | ||
return &NamespacedFeature{*feature, *namespace} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package database | ||
|
||
// Layer is a layer with all the detected features and namespaces. | ||
type Layer struct { | ||
// Hash is the sha-256 tarsum on the layer's blob content. | ||
Hash string `json:"hash"` | ||
// By contains a list of detectors scanned this Layer. | ||
By []Detector `json:"by"` | ||
Namespaces []LayerNamespace `json:"namespaces"` | ||
Features []LayerFeature `json:"features"` | ||
} | ||
|
||
func (l *Layer) GetFeatures() []Feature { | ||
features := make([]Feature, 0, len(l.Features)) | ||
for _, f := range l.Features { | ||
features = append(features, f.Feature) | ||
} | ||
|
||
return features | ||
} | ||
|
||
func (l *Layer) GetNamespaces() []Namespace { | ||
namespaces := make([]Namespace, 0, len(l.Namespaces)) | ||
for _, ns := range l.Namespaces { | ||
namespaces = append(namespaces, ns.Namespace) | ||
} | ||
|
||
return namespaces | ||
} | ||
|
||
// LayerNamespace is a namespace with detection information. | ||
type LayerNamespace struct { | ||
Namespace `json:"namespace"` | ||
|
||
// By is the detector found the namespace. | ||
By Detector `json:"by"` | ||
} | ||
|
||
// LayerFeature is a feature with detection information. | ||
type LayerFeature struct { | ||
Feature `json:"feature"` | ||
|
||
// By is the detector found the feature. | ||
By Detector `json:"by"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package database | ||
|
||
import ( | ||
"database/sql/driver" | ||
"encoding/json" | ||
) | ||
|
||
// MetadataMap is for storing the metadata returned by vulnerability database. | ||
type MetadataMap map[string]interface{} | ||
|
||
func (mm *MetadataMap) Scan(value interface{}) error { | ||
if value == nil { | ||
return nil | ||
} | ||
|
||
// github.com/lib/pq decodes TEXT/VARCHAR fields into strings. | ||
val, ok := value.(string) | ||
if !ok { | ||
panic("got type other than []byte from database") | ||
} | ||
return json.Unmarshal([]byte(val), mm) | ||
} | ||
|
||
func (mm *MetadataMap) Value() (driver.Value, error) { | ||
json, err := json.Marshal(*mm) | ||
return string(json), err | ||
} |
Oops, something went wrong.