Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add license info #3

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .project
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>meta-dependencytrack</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>
62 changes: 57 additions & 5 deletions classes/dependency-track.bbclass
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,15 @@ DEPENDENCYTRACK_SBOM ??= "${DEPENDENCYTRACK_DIR}/bom.json"
DEPENDENCYTRACK_TMP ??= "${TMPDIR}/dependency-track"
DEPENDENCYTRACK_LOCK ??= "${DEPENDENCYTRACK_TMP}/bom.lock"

# Set DEPENDENCYTRACK_UPLOAD to False if you want to control the upload in other
# steps.
DEPENDENCYTRACK_UPLOAD ??= "True"
DEPENDENCYTRACK_PROJECT ??= ""
DEPENDENCYTRACK_API_URL ??= "http://localhost:8081/api"
DEPENDENCYTRACK_API_KEY ??= ""

DT_LICENSE_CONVERSION_MAP ??= '{ "GPLv2+" : "GPL-2.0-or-later", "GPLv2" : "GPL-2.0", "LGPLv2" : "LGPL-2.0", "LGPLv2+" : "LGPL-2.0-or-later", "LGPLv2.1+" : "LGPL-2.1-or-later", "LGPLv2.1" : "LGPL-2.1"}'

python do_dependencytrack_init() {
import uuid
from datetime import datetime
Expand Down Expand Up @@ -53,11 +58,15 @@ python do_dependencytrack_collect() {
for index, cpe in enumerate(oe.cve_check.get_cpe_ids(name, version)):
bb.debug(2, f"Collecting pagkage {name}@{version} ({cpe})")
if not next((c for c in sbom["components"] if c["cpe"] == cpe), None):
sbom["components"].append({
component_json = {
"name": names[index],
"version": version,
"cpe": cpe
})
"cpe": cpe,
}
license_json = get_licenses(d)
if license_json:
component_json["licenses"] = license_json
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line gives a structure like
"licenses": [
{
"license": {

according to

https://cyclonedx.org/use-cases/#license-compliance

Can you check if you have this structure in the SBOM?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's in the right structure, or I don't see the failure myself. But dependency-track still don't show the licenses if I upload the sbom to the api.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried this:
# update it with the new package info
names = name.split()
for index, cpe in enumerate(oe.cve_check.get_cpe_ids(name, version)):
bb.debug(2, f"Collecting pagkage {name}@{version} ({cpe})")
if not next((c for c in sbom["components"] if c["cpe"] == cpe), None):
sbom["components"].append({
"name": names[index],
"version": version,
"cpe": cpe,
"licenses" : [
{
"license" : {
"id" : license
}
}]
})

before your last update and it shows like 50% of the licenses.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the missing licenses are the ones which has more then one license.

sbom["components"].append(component_json)

# write it back to the deploy directory
write_sbom(d, sbom)
Expand All @@ -74,6 +83,10 @@ python do_dependencytrack_upload () {
import urllib
from pathlib import Path

dt_upload = bb.utils.to_boolean(d.getVar('DEPENDENCYTRACK_UPLOAD'))
if not dt_upload:
return

sbom_path = d.getVar("DEPENDENCYTRACK_SBOM")
dt_project = d.getVar("DEPENDENCYTRACK_PROJECT")
dt_url = f"{d.getVar('DEPENDENCYTRACK_API_URL')}/v1/bom"
Expand All @@ -86,7 +99,7 @@ python do_dependencytrack_upload () {
"bom": base64.b64encode(sbom.encode()).decode('ascii')
}).encode()
bb.debug(2, f"Uploading SBOM to project {dt_project} at {dt_url}")

headers = {
"Content-Type": "application/json",
"X-API-Key": d.getVar("DEPENDENCYTRACK_API_KEY")
Expand All @@ -96,7 +109,7 @@ python do_dependencytrack_upload () {
data=payload,
headers=headers,
method="PUT")

try:
urllib.request.urlopen(req)
except urllib.error.HTTPError as e:
Expand All @@ -120,3 +133,42 @@ def write_sbom(d, sbom):
Path(d.getVar("DEPENDENCYTRACK_SBOM")).write_text(
json.dumps(sbom, indent=2)
)

def get_licenses(d) :
from pathlib import Path
import json
license_expression = d.getVar("LICENSE")
if license_expression:
license_json = []
licenses = license_expression.replace("|", "").replace("&", "").split()
for license in licenses:
license_conversion_map = json.loads(d.getVar('DT_LICENSE_CONVERSION_MAP'))
converted_license = None
try:
converted_license = license_conversion_map[license]
except Exception as e:
pass
if not converted_license:
converted_license = license
# Search for the license in COMMON_LICENSE_DIR and LICENSE_PATH
for directory in [d.getVar('COMMON_LICENSE_DIR')] + (d.getVar('LICENSE_PATH') or '').split():
try:
with (Path(directory) / converted_license).open(errors="replace") as f:
extractedText = f.read()
license_data = {
"license": {
"name" : converted_license,
"text": {
"contentType": "text/plain",
"content": extractedText
}
}
}
license_json.append(license_data)
break
except FileNotFoundError:
pass
license_json.append({"expression" : license_expression})
return license_json
return None