From 68250f392b7820c30ee042a905ff9eb25860c186 Mon Sep 17 00:00:00 2001 From: Jimmy Zelinskie Date: Wed, 16 Mar 2016 14:52:32 -0400 Subject: [PATCH] api/v1: create namespace type This change creates a struct type for namespaces rather than using a string. This enables us to extend namespaces in the future to contain metadata. This change also required renaming other field references of namespaces to "NamespaceName". Fixes #99 --- api/v1/README.md | 42 ++++++++-------- api/v1/models.go | 74 +++++++++++++++------------- api/v1/routes.go | 4 +- contrib/analyze-local-images/main.go | 2 +- 4 files changed, 63 insertions(+), 59 deletions(-) diff --git a/api/v1/README.md b/api/v1/README.md index 96388eb8..f13b948d 100644 --- a/api/v1/README.md +++ b/api/v1/README.md @@ -122,18 +122,18 @@ Server: clair { "Layer": { "Name": "17675ec01494d651e1ccf81dc9cf63959ebfeed4f978fddb1666b6ead008ed52", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "ParentName": "140f9bdfeb9784cf8730e9dab5dd12fbd704151cf555ac8cae650451794e5ac2", "IndexedByVersion": 1, "Features": [ { "Name": "coreutils", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "Version": "8.23-4", "Vulnerabilities": [ { "Name": "CVE-2014-9471", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "Description": "The parse_datetime function in GNU coreutils allows remote attackers to cause a denial of service (crash) or possibly execute arbitrary code via a crafted date string, as demonstrated by the \"--date=TZ=\"123\"345\" @1\" string to the touch or date command.", "Link": "https://security-tracker.debian.org/tracker/CVE-2014-9471", "Severity": "Low", @@ -189,8 +189,8 @@ Server: clair { "Namespaces": [ - "debian:8", - "debian:9" + { "Name": "debian:8" }, + { "Name": "debian:9" } ] } ``` @@ -227,14 +227,14 @@ Server: clair "Vulnerabilities": [ { "Name": "CVE-1999-1332", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "Description": "gzexe in the gzip package on Red Hat Linux 5.0 and earlier allows local users to overwrite files of other users via a symlink attack on a temporary file.", "Link": "https://security-tracker.debian.org/tracker/CVE-1999-1332", "Severity": "Low" }, { "Name": "CVE-1999-1572", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "Description": "cpio on FreeBSD 2.1.0, Debian GNU/Linux 3.0, and possibly other operating systems, uses a 0 umask when creating files using the -O (archive) or -F options, which creates the files with mode 0666 and allows local users to read or overwrite those files.", "Link": "https://security-tracker.debian.org/tracker/CVE-1999-1572", "Severity": "Low", @@ -266,7 +266,7 @@ POST http://localhost:6060/v1/namespaces/debian%3A8/vulnerabilities HTTP/1.1 { "Vulnerability": { "Name": "CVE-2014-9471", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "Link": "https://security-tracker.debian.org/tracker/CVE-2014-9471", "Description": "The parse_datetime function in GNU coreutils allows remote attackers to cause a denial of service (crash) or possibly execute arbitrary code via a crafted date string, as demonstrated by the \"--date=TZ=\"123\"345\" @1\" string to the touch or date command.", "Severity": "Low", @@ -281,7 +281,7 @@ POST http://localhost:6060/v1/namespaces/debian%3A8/vulnerabilities HTTP/1.1 "FixedIn": [ { "Name": "coreutils", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "Version": "8.23-1" } ] @@ -299,7 +299,7 @@ Server: clair { "Vulnerability": { "Name": "CVE-2014-9471", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "Link": "https://security-tracker.debian.org/tracker/CVE-2014-9471", "Description": "The parse_datetime function in GNU coreutils allows remote attackers to cause a denial of service (crash) or possibly execute arbitrary code via a crafted date string, as demonstrated by the \"--date=TZ=\"123\"345\" @1\" string to the touch or date command.", "Severity": "Low", @@ -314,7 +314,7 @@ Server: clair "FixedIn": [ { "Name": "coreutils", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "Version": "8.23-1" } ] @@ -350,7 +350,7 @@ Server: clair { "Vulnerability": { "Name": "CVE-2014-9471", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "Link": "https://security-tracker.debian.org/tracker/CVE-2014-9471", "Description": "The parse_datetime function in GNU coreutils allows remote attackers to cause a denial of service (crash) or possibly execute arbitrary code via a crafted date string, as demonstrated by the \"--date=TZ=\"123\"345\" @1\" string to the touch or date command.", "Severity": "Low", @@ -365,7 +365,7 @@ Server: clair "FixedIn": [ { "Name": "coreutils", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "Version": "8.23-1" } ] @@ -390,7 +390,7 @@ PUT http://localhost:6060/v1/namespaces/debian%3A8/vulnerabilities/CVE-2014-9471 { "Vulnerability": { "Name": "CVE-2014-9471", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "Link": "https://security-tracker.debian.org/tracker/CVE-2014-9471", "Description": "The parse_datetime function in GNU coreutils allows remote attackers to cause a denial of service (crash) or possibly execute arbitrary code via a crafted date string, as demonstrated by the \"--date=TZ=\"123\"345\" @1\" string to the touch or date command.", "Severity": "Low", @@ -415,7 +415,7 @@ Server: clair { "Vulnerability": { "Name": "CVE-2014-9471", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "Link": "https://security-tracker.debian.org/tracker/CVE-2014-9471", "Description": "The parse_datetime function in GNU coreutils allows remote attackers to cause a denial of service (crash) or possibly execute arbitrary code via a crafted date string, as demonstrated by the \"--date=TZ=\"123\"345\" @1\" string to the touch or date command.", "Severity": "Low", @@ -477,7 +477,7 @@ Server: clair "Features": [ { "Name": "coreutils", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "Version": "8.23-1" } ] @@ -498,7 +498,7 @@ PUT http://localhost:6060/v1/namespaces/debian%3A8/vulnerabilities/CVE-2014-9471 { "Feature": { "Name": "coreutils", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "Version": "4.24-9" } } @@ -513,7 +513,7 @@ Server: clair { "Feature": { "Name": "coreutils", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "Version": "4.24-9" } } @@ -578,13 +578,13 @@ Server: clair "New": { "Vulnerability": { "Name": "CVE-TEST", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "Description": "New CVE", "Severity": "Low", "FixedIn": [ { "Name": "grep", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "Version": "2.25" } ] @@ -597,7 +597,7 @@ Server: clair "Old": { "Vulnerability": { "Name": "CVE-TEST", - "Namespace": "debian:8", + "NamespaceName": "debian:8", "Description": "New CVE", "Severity": "Low", "FixedIn": [] diff --git a/api/v1/models.go b/api/v1/models.go index f3b3c5e0..f5498eb5 100644 --- a/api/v1/models.go +++ b/api/v1/models.go @@ -35,7 +35,7 @@ type Error struct { type Layer struct { Name string `json:"Name,omitempty"` - Namespace string `json:"Namespace,omitempty"` + NamespaceName string `json:"NamespaceName,omitempty"` Path string `json:"Path,omitempty"` ParentName string `json:"ParentName,omitempty"` Format string `json:"Format,omitempty"` @@ -54,26 +54,26 @@ func LayerFromDatabaseModel(dbLayer database.Layer, withFeatures, withVulnerabil } if dbLayer.Namespace != nil { - layer.Namespace = dbLayer.Namespace.Name + layer.NamespaceName = dbLayer.Namespace.Name } if withFeatures || withVulnerabilities && dbLayer.Features != nil { for _, dbFeatureVersion := range dbLayer.Features { feature := Feature{ - Name: dbFeatureVersion.Feature.Name, - Namespace: dbFeatureVersion.Feature.Namespace.Name, - Version: dbFeatureVersion.Version.String(), - AddedBy: dbFeatureVersion.AddedBy.Name, + Name: dbFeatureVersion.Feature.Name, + NamespaceName: dbFeatureVersion.Feature.Namespace.Name, + Version: dbFeatureVersion.Version.String(), + AddedBy: dbFeatureVersion.AddedBy.Name, } for _, dbVuln := range dbFeatureVersion.AffectedBy { vuln := Vulnerability{ - Name: dbVuln.Name, - Namespace: dbVuln.Namespace.Name, - Description: dbVuln.Description, - Link: dbVuln.Link, - Severity: string(dbVuln.Severity), - Metadata: dbVuln.Metadata, + Name: dbVuln.Name, + NamespaceName: dbVuln.Namespace.Name, + Description: dbVuln.Description, + Link: dbVuln.Link, + Severity: string(dbVuln.Severity), + Metadata: dbVuln.Metadata, } if dbVuln.FixedBy != types.MaxVersion { @@ -88,15 +88,19 @@ func LayerFromDatabaseModel(dbLayer database.Layer, withFeatures, withVulnerabil return layer } +type Namespace struct { + Name string `json:"Name,omitempty"` +} + type Vulnerability struct { - Name string `json:"Name,omitempty"` - Namespace string `json:"Namespace,omitempty"` - Description string `json:"Description,omitempty"` - Link string `json:"Link,omitempty"` - Severity string `json:"Severity,omitempty"` - Metadata map[string]interface{} `json:"Metadata,omitempty"` - FixedBy string `json:"FixedBy,omitempty"` - FixedIn []Feature `json:"FixedIn,omitempty"` + Name string `json:"Name,omitempty"` + NamespaceName string `json:"NamespaceName,omitempty"` + Description string `json:"Description,omitempty"` + Link string `json:"Link,omitempty"` + Severity string `json:"Severity,omitempty"` + Metadata map[string]interface{} `json:"Metadata,omitempty"` + FixedBy string `json:"FixedBy,omitempty"` + FixedIn []Feature `json:"FixedIn,omitempty"` } func (v Vulnerability) DatabaseModel() (database.Vulnerability, error) { @@ -117,7 +121,7 @@ func (v Vulnerability) DatabaseModel() (database.Vulnerability, error) { return database.Vulnerability{ Name: v.Name, - Namespace: database.Namespace{Name: v.Namespace}, + Namespace: database.Namespace{Name: v.NamespaceName}, Description: v.Description, Link: v.Link, Severity: severity, @@ -128,12 +132,12 @@ func (v Vulnerability) DatabaseModel() (database.Vulnerability, error) { func VulnerabilityFromDatabaseModel(dbVuln database.Vulnerability, withFixedIn bool) Vulnerability { vuln := Vulnerability{ - Name: dbVuln.Name, - Namespace: dbVuln.Namespace.Name, - Description: dbVuln.Description, - Link: dbVuln.Link, - Severity: string(dbVuln.Severity), - Metadata: dbVuln.Metadata, + Name: dbVuln.Name, + NamespaceName: dbVuln.Namespace.Name, + Description: dbVuln.Description, + Link: dbVuln.Link, + Severity: string(dbVuln.Severity), + Metadata: dbVuln.Metadata, } if withFixedIn { @@ -147,7 +151,7 @@ func VulnerabilityFromDatabaseModel(dbVuln database.Vulnerability, withFixedIn b type Feature struct { Name string `json:"Name,omitempty"` - Namespace string `json:"Namespace,omitempty"` + NamespaceName string `json:"NamespaceName,omitempty"` Version string `json:"Version,omitempty"` Vulnerabilities []Vulnerability `json:"Vulnerabilities,omitempty"` AddedBy string `json:"AddedBy,omitempty"` @@ -160,10 +164,10 @@ func FeatureFromDatabaseModel(dbFeatureVersion database.FeatureVersion) Feature } return Feature{ - Name: dbFeatureVersion.Feature.Name, - Namespace: dbFeatureVersion.Feature.Namespace.Name, - Version: versionStr, - AddedBy: dbFeatureVersion.AddedBy.Name, + Name: dbFeatureVersion.Feature.Name, + NamespaceName: dbFeatureVersion.Feature.Namespace.Name, + Version: versionStr, + AddedBy: dbFeatureVersion.AddedBy.Name, } } @@ -182,7 +186,7 @@ func (f Feature) DatabaseModel() (database.FeatureVersion, error) { return database.FeatureVersion{ Feature: database.Feature{ Name: f.Name, - Namespace: database.Namespace{Name: f.Namespace}, + Namespace: database.Namespace{Name: f.NamespaceName}, }, Version: version, }, nil @@ -270,8 +274,8 @@ type LayerEnvelope struct { } type NamespaceEnvelope struct { - Namespaces *[]string `json:"Namespaces,omitempty"` - Error *Error `json:"Error,omitempty"` + Namespaces *[]Namespace `json:"Namespaces,omitempty"` + Error *Error `json:"Error,omitempty"` } type VulnerabilityEnvelope struct { diff --git a/api/v1/routes.go b/api/v1/routes.go index 3edbe769..408bd8c5 100644 --- a/api/v1/routes.go +++ b/api/v1/routes.go @@ -176,9 +176,9 @@ func getNamespaces(w http.ResponseWriter, r *http.Request, p httprouter.Params, writeResponse(w, r, http.StatusInternalServerError, NamespaceEnvelope{Error: &Error{err.Error()}}) return getNamespacesRoute, http.StatusInternalServerError } - var namespaces []string + var namespaces []Namespace for _, dbNamespace := range dbNamespaces { - namespaces = append(namespaces, dbNamespace.Name) + namespaces = append(namespaces, Namespace{Name: dbNamespace.Name}) } writeResponse(w, r, http.StatusOK, NamespaceEnvelope{Namespaces: &namespaces}) diff --git a/contrib/analyze-local-images/main.go b/contrib/analyze-local-images/main.go index 9f67d5f7..62c933e5 100644 --- a/contrib/analyze-local-images/main.go +++ b/contrib/analyze-local-images/main.go @@ -127,7 +127,7 @@ func main() { isSafe := true for _, feature := range layer.Features { - fmt.Printf("## Feature: %s %s (%s)\n", feature.Name, feature.Version, feature.Namespace) + fmt.Printf("## Feature: %s %s (%s)\n", feature.Name, feature.Version, feature.NamespaceName) if len(feature.Vulnerabilities) > 0 { isSafe = false