Skip to content

Commit

Permalink
Implement new IsDependency graphql to point to versions (#1125)
Browse files Browse the repository at this point in the history
* change IsDepedency graphQL schema

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

* regenerate gql codegen

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

* update to compile and only implementing backward compatibility without new depVersion depPkg

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

* update parsers and tests to default to deps to names

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

* update parsers to use new version dep when necessary

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

* implement inmem deppkg match

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

* update vulnerability CLI to handle new depedency structure

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

* change patchPlanning to handle new isDep change

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

* arangoDB isDep edits (partial)

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

* update isDependency tests to test for new behavior

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

* add use of nilIfEmpty

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

* update e2e test expectIsDependencyQ2

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

* minor fmting err with expectIsDependencyQ2.json

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

* update isDep for dep pkgName and pkgVersion, update dbPkgVersion and remove unneeded code

Signed-off-by: pxp928 <parth.psu@gmail.com>

* fix rebase merge

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

* fix gql comment typo

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

* update make generate

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

* update e2e tests to work with new IsDep def

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

* fix e2e expect json

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

* fix certifyVuln from rebase changes

Signed-off-by: Brandon Lum <lumjjb@gmail.com>

---------

Signed-off-by: Brandon Lum <lumjjb@gmail.com>
Signed-off-by: pxp928 <parth.psu@gmail.com>
Co-authored-by: pxp928 <parth.psu@gmail.com>
  • Loading branch information
lumjjb and pxp928 committed Aug 17, 2023
1 parent e55fa24 commit 5f19f1c
Show file tree
Hide file tree
Showing 40 changed files with 1,056 additions and 591 deletions.
31 changes: 24 additions & 7 deletions cmd/guacgql/cmd/ingest.go
Expand Up @@ -186,12 +186,14 @@ func ingestDependency(ctx context.Context, client graphql.Client) {
ns := "ubuntu"
version := "1.19.0.4"
depns := "openssl.org"
opensslVersion := "3.0.3"
smartentryNs := "smartentry"
ingestDependencies := []struct {
name string
pkg model.PkgInputSpec
depPkg model.PkgInputSpec
dependency model.IsDependencyInputSpec
name string
pkg model.PkgInputSpec
depPkg model.PkgInputSpec
depPkgMatchFlags model.MatchFlags
dependency model.IsDependencyInputSpec
}{
{
name: "deb: part of SBOM - openssl",
Expand All @@ -209,6 +211,7 @@ func ingestDependency(ctx context.Context, client graphql.Client) {
Namespace: &depns,
Name: "openssl",
},
depPkgMatchFlags: model.MatchFlags{Pkg: model.PkgMatchTypeAllVersions},
dependency: model.IsDependencyInputSpec{
VersionRange: "3.0.3",
DependencyType: model.DependencyTypeDirect,
Expand All @@ -228,7 +231,13 @@ func ingestDependency(ctx context.Context, client graphql.Client) {
Type: "conan",
Namespace: &depns,
Name: "openssl",
Version: &opensslVersion,
Qualifiers: []model.PackageQualifierInputSpec{
{Key: "user", Value: "bincrafters"},
{Key: "channel", Value: "stable"},
},
},
depPkgMatchFlags: model.MatchFlags{Pkg: model.PkgMatchTypeSpecificVersion},
dependency: model.IsDependencyInputSpec{
VersionRange: "3.0.3",
DependencyType: model.DependencyTypeIndirect,
Expand All @@ -238,7 +247,7 @@ func ingestDependency(ctx context.Context, client graphql.Client) {
},
},
{
name: "deb: part of SBOM - openssl (duplicate)",
name: "deb: part of SBOM - openssl (indirect)",
pkg: model.PkgInputSpec{
Type: "deb",
Namespace: &ns,
Expand All @@ -252,7 +261,13 @@ func ingestDependency(ctx context.Context, client graphql.Client) {
Type: "conan",
Namespace: &depns,
Name: "openssl",
Version: &opensslVersion,
Qualifiers: []model.PackageQualifierInputSpec{
{Key: "user", Value: "bincrafters"},
{Key: "channel", Value: "stable"},
},
},
depPkgMatchFlags: model.MatchFlags{Pkg: model.PkgMatchTypeSpecificVersion},
dependency: model.IsDependencyInputSpec{
VersionRange: "3.0.3",
DependencyType: model.DependencyTypeDirect,
Expand All @@ -269,7 +284,7 @@ func ingestDependency(ctx context.Context, client graphql.Client) {
if _, err := model.IngestPackage(ctx, client, ingest.depPkg); err != nil {
logger.Errorf("Error in ingesting dependency package: %v\n", err)
}
if _, err := model.IsDependency(ctx, client, ingest.pkg, ingest.depPkg, ingest.dependency); err != nil {
if _, err := model.IsDependency(ctx, client, ingest.pkg, ingest.depPkg, ingest.depPkgMatchFlags, ingest.dependency); err != nil {
logger.Errorf("Error in ingesting: %v\n", err)
}
}
Expand Down Expand Up @@ -2306,6 +2321,7 @@ func ingestReachabilityTestData(ctx context.Context, client graphql.Client) {
depPkg model.PkgInputSpec
dependency model.IsDependencyInputSpec
depPkgWithVersion model.PkgInputSpec
depPkgMatchFlags model.MatchFlags
art model.ArtifactInputSpec
occurrence model.IsOccurrenceInputSpec
source model.SourceInputSpec
Expand All @@ -2331,6 +2347,7 @@ func ingestReachabilityTestData(ctx context.Context, client graphql.Client) {
Namespace: &depns,
Name: "openssl",
},
depPkgMatchFlags: model.MatchFlags{Pkg: model.PkgMatchTypeAllVersions},
dependency: model.IsDependencyInputSpec{
VersionRange: "3.0.3",
DependencyType: model.DependencyTypeDirect,
Expand Down Expand Up @@ -2411,7 +2428,7 @@ func ingestReachabilityTestData(ctx context.Context, client graphql.Client) {
if _, err := model.IngestVulnerability(ctx, client, *ingest.vuln); err != nil {
logger.Errorf("Error in ingesting vuln: %v\n", err)
}
if _, err := model.IsDependency(ctx, client, ingest.pkg, ingest.depPkg, ingest.dependency); err != nil {
if _, err := model.IsDependency(ctx, client, ingest.pkg, ingest.depPkg, ingest.depPkgMatchFlags, ingest.dependency); err != nil {
logger.Errorf("Error in ingesting: %v\n", err)
}
if _, err := model.IsOccurrencePkg(ctx, client, ingest.depPkgWithVersion, ingest.art, ingest.occurrence); err != nil {
Expand Down
18 changes: 17 additions & 1 deletion cmd/guacone/cmd/vulnerability.go
Expand Up @@ -411,7 +411,7 @@ func searchDependencyPackagesReverse(ctx context.Context, gqlclient graphql.Clie
return nil, fmt.Errorf("failed getting package parent:%v", err)
}
for _, neighbor := range isDependencyNeighborResponses.Neighbors {
if isDependency, ok := neighbor.(*model.NeighborsNeighborsIsDependency); ok {
if isDependency, ok := neighbor.(*model.NeighborsNeighborsIsDependency); ok && now != isDependency.Package.Namespaces[0].Names[0].Versions[0].Id {
dfsN, seen := nodeMap[isDependency.Package.Namespaces[0].Names[0].Versions[0].Id]
if !seen {
dfsN = dfsNode{
Expand All @@ -428,6 +428,22 @@ func searchDependencyPackagesReverse(ctx context.Context, gqlclient graphql.Clie
}
}
}
if isDependency, ok := neighbor.(*model.NeighborsNeighborsIsDependency); ok && now != isDependency.Package.Namespaces[0].Names[0].Versions[0].Id {
dfsN, seen := nodeMap[isDependency.Package.Namespaces[0].Names[0].Versions[0].Id]
if !seen {
dfsN = dfsNode{
parent: now,
isDependency: isDependency,
depth: nowNode.depth + 1,
}
nodeMap[isDependency.Package.Namespaces[0].Names[0].Versions[0].Id] = dfsN
}
if !dfsN.expanded {
queue = append(queue, isDependency.Package.Namespaces[0].Names[0].Versions[0].Id)
collectedIDs = append(collectedIDs, isDependency.Package.Namespaces[0].Names[0].Versions[0].Id)
}
}

}

nowNode.expanded = true
Expand Down
14 changes: 11 additions & 3 deletions demo/graphql/path.py
Expand Up @@ -41,6 +41,13 @@ def deepID(node):
pass
return node['id']

def isPackageVersion(node):
try:
retrieve = (node['namespaces'][0]['names'][0]['versions'][0])
return True
except:
return False

# guacID returns the ID of a GUAC node. For nouns, the deepest ID is the ID,
# for verbs, it is the top level ID.
def guacID(node):
Expand Down Expand Up @@ -71,9 +78,9 @@ def containsID(node, id):
# bfs finds the shortest path fron start to target, while applying filter() to
# only search in certian ways.
def bfs(startID, targetID):
visited = []
visited = set([])
queue = []
visited.append(startID)
visited.add(startID)
queue.append({'id': startID, 'path': [ startID ], 'pathNodes': [ nodeQuery(startID) ]})
while queue:
node = queue.pop(0)
Expand All @@ -90,7 +97,7 @@ def bfs(startID, targetID):
newNodePath.append(n)
if nodeID == targetID:
return (newPath, newNodePath)
visited.append(nodeID)
visited.add(nodeID)
queue.append({'id': nodeID, 'path': newPath, 'pathNodes': newNodePath})
return [], []

Expand All @@ -100,6 +107,7 @@ def filter(fromID, fromNode, neighbor):
if neighbor['__typename'] == 'Package':
# From Package -> Package, only search downwards
if fromNode['__typename'] == 'Package':
return isPackageVersion(neighbor)
return containsID(neighbor, fromID)
# From other node type -> Package is ok.
return True
Expand Down
4 changes: 4 additions & 0 deletions demo/graphql/queries.gql
Expand Up @@ -230,6 +230,10 @@ query PkgQ8 {
names {
id
name
versions {
id
version
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions internal/testing/e2e/e2e
Expand Up @@ -77,9 +77,9 @@ cat "$queries" | gql-cli http://localhost:8080/query -o CertifyVulnQ1 | jq 'del(
diff -u "${SCRIPT_DIR}/expectCertifyVulnQ1.json" "${GUAC_DIR}/gotCertifyVulnQ1.json"

id3=$(cat "$queries" | gql-cli http://localhost:8080/query -o PkgQ7 | jq -r ' .packages[0].namespaces[0].names[0].id ')
id4=$(cat "$queries" | gql-cli http://localhost:8080/query -o PkgQ8 | jq -r ' .packages[0].namespaces[0].names[0].id ')
id4=$(cat "$queries" | gql-cli http://localhost:8080/query -o PkgQ8 | jq -r ' .packages[0].namespaces[0].names[0].versions[0].id ')

"${GUAC_DIR}/demo/graphql/path.py" $id3 $id4 | tail -n +2 | jq 'del(.. | .id?) | del(.. | .origin?)' > "${GUAC_DIR}/gotPathPy.json"
"${GUAC_DIR}/demo/graphql/path.py" $id3 $id4 | tail -n +2 | jq 'del(.. | .id?) | del(.. | .origin?) | del(.. | .qualifiers?)' > "${GUAC_DIR}/gotPathPy.json"
diff -u "${SCRIPT_DIR}/expectPathPy.json" "${GUAC_DIR}/gotPathPy.json"

# Note: graphql_playground is left running, CI will clean it up
8 changes: 7 additions & 1 deletion internal/testing/e2e/expectIsDependencyQ2.json
Expand Up @@ -36,7 +36,13 @@
"names": [
{
"name": "logrus",
"versions": []
"versions": [
{
"version": "v1.4.2",
"qualifiers": [],
"subpath": ""
}
]
}
]
}
Expand Down
26 changes: 12 additions & 14 deletions internal/testing/e2e/expectPathPy.json
Expand Up @@ -26,12 +26,6 @@
"versions": [
{
"version": "sha256:e9ebb760d74df0c28447c2f67050800c3392a3987ed77ce493545c7d3ad24c9d",
"qualifiers": [
{
"key": "tag",
"value": "latest"
}
],
"subpath": ""
}
]
Expand All @@ -55,12 +49,6 @@
"versions": [
{
"version": "sha256:e9ebb760d74df0c28447c2f67050800c3392a3987ed77ce493545c7d3ad24c9d",
"qualifiers": [
{
"key": "tag",
"value": "latest"
}
],
"subpath": ""
}
]
Expand All @@ -77,7 +65,12 @@
"names": [
{
"name": "libsqlite3-dev",
"versions": []
"versions": [
{
"version": "3.34.1-3",
"subpath": ""
}
]
}
]
}
Expand All @@ -94,7 +87,12 @@
"names": [
{
"name": "libsqlite3-dev",
"versions": []
"versions": [
{
"version": "3.34.1-3",
"subpath": ""
}
]
}
]
}
Expand Down
6 changes: 6 additions & 0 deletions internal/testing/testdata/exampledata/ingest_predicates.json
Expand Up @@ -87,6 +87,9 @@
],
"subpath": ""
},
"depPkgMatchFlag" : {
"pkg": "SPECIFIC_VERSION"
},
"isDependency": {
"versionRange": "3.2.0-r22",
"dependencyType": "UNKNOWN",
Expand Down Expand Up @@ -125,6 +128,9 @@
],
"subpath": ""
},
"depPkgMatchFlag" : {
"pkg": "SPECIFIC_VERSION"
},
"isDependency": {
"versionRange": "3.2.0-r22",
"dependencyType": "UNKNOWN",
Expand Down

0 comments on commit 5f19f1c

Please sign in to comment.