Commit ae64a615 authored by Marc Barussaud's avatar Marc Barussaud
Browse files

Merge branch '5-allow-properties-tag-on-creation' into 'main'

Resolve "Allow properties / tag on creation"

Closes #5

See merge request to-be-continuous/tools/dt-sbom-scanner!47
parents 2af78ceb e4371cf7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ If none is specified, the program will look for SBOM files matching `**/*.cyclon
| `-m` / `--merge`                | `$DEPTRACK_MERGE`                 | Merge all SBOM files into one (default `false`)                                 |
| `-o` / `--merge-output`         | `$DEPTRACK_MERGE_OUTPUT`          | Output merged SBOM file (only used with merge enabled) - for debugging purpose  |
| `-l` / `--purl-max-len`         | `$DEPTRACK_PURL_MAX_LEN`          | PURLs max length (`-1`: auto, `0`: no trim, `>0`: trim to size - default: `-1`) |
| `-t` / `--tags`                 | `$DEPTRACK_TAGS`                  | Comma seperated list of tags to put in the project in autoCreate mode |
| `-S` / `--show-findings`        | `$DEPTRACK_SHOW_FINDINGS`         | Wait for analysis and display found vulnerabilities                             |
| `-R` / `--risk-score-threshold` | `$DEPTRACK_RISK_SCORE_THRESHOLD`  | Risk score threshold to fail the scan (`<0`: disabled - default: `-1`)          |
| `-i` / `--insecure`             | `$DEPTRACK_INSECURE`              | Skip SSL verification                                                           |
+23 −7
Original line number Diff line number Diff line
@@ -22,7 +22,9 @@ def load_bom(file: Path) -> Bom:

    def component_patched(self, **kwargs):
        if "bom_ref" not in kwargs:
            print(f"{AnsiColors.YELLOW}{AnsiColors.RESET} missing 'bom_ref' in component {AnsiColors.HGRAY}{kwargs.get('name')}@{kwargs.get('version')}{AnsiColors.RESET} ({kwargs['type'].value}): fix")
            print(
                f"{AnsiColors.YELLOW}{AnsiColors.RESET} missing 'bom_ref' in component {AnsiColors.HGRAY}{kwargs.get('name')}@{kwargs.get('version')}{AnsiColors.RESET} ({kwargs['type'].value}): fix"
            )
            kwargs["bom_ref"] = kwargs["name"]
        component_init(self, **kwargs)

@@ -50,7 +52,9 @@ def load_bom(file: Path) -> Bom:

        if warnings:
            for w in warnings:
                print(f"{AnsiColors.YELLOW}{AnsiColors.RESET} l#{w.lineno}: {w.message}")
                print(
                    f"{AnsiColors.YELLOW}{AnsiColors.RESET} l#{w.lineno}: {w.message}"
                )
    except Exception as e:
        raise ValueError(f"Error while loading SBOM: {file.name}") from e

@@ -77,17 +81,25 @@ def trim_purls(sbom: Bom, limit: int = 0) -> None:
            continue

        while purl.qualifiers and len(purl_trunc) >= limit:
            longest_key = max(purl.qualifiers, key=lambda key: len(purl.qualifiers[key]))
            longest_key = max(
                purl.qualifiers, key=lambda key: len(purl.qualifiers[key])
            )
            purl.qualifiers.pop(longest_key)
            purl_trunc = str(purl)

        if len(str(purl)) >= limit:
            print(f"{AnsiColors.YELLOW}{AnsiColors.RESET} trimmed {purl_orig} -> {AnsiColors.HGRAY}{purl_trunc}{AnsiColors.RESET} but still exceeds limit ({limit})")
            print(
                f"{AnsiColors.YELLOW}{AnsiColors.RESET} trimmed {purl_orig} -> {AnsiColors.HGRAY}{purl_trunc}{AnsiColors.RESET} but still exceeds limit ({limit})"
            )
        else:
            print(f"{AnsiColors.GREEN}{AnsiColors.RESET} successfully trimmed {purl_orig} -> {AnsiColors.HGRAY}{purl_trunc}{AnsiColors.RESET}")
            print(
                f"{AnsiColors.GREEN}{AnsiColors.RESET} successfully trimmed {purl_orig} -> {AnsiColors.HGRAY}{purl_trunc}{AnsiColors.RESET}"
            )


def serialize(bom: Bom, format=OutputFormat.JSON, schema_version=SchemaVersion.V1_5) -> str:
def serialize(
    bom: Bom, format=OutputFormat.JSON, schema_version=SchemaVersion.V1_5
) -> str:
    return make_outputter(bom, format, schema_version).output_as_string()


@@ -148,7 +160,11 @@ def merge_boms(
            if all(c.bom_ref != component.bom_ref for c in merged.components):
                if component in merged.components:
                    # allow duplicated component by adding an unique metadata
                    component.properties.add(Property(name="dt:merge-deduplicate", value=component.bom_ref.value))
                    component.properties.add(
                        Property(
                            name="dt:merge-deduplicate", value=component.bom_ref.value
                        )
                    )
                merged.components.add(component)
            if parent and component.bom_ref not in depended:
                merged.register_dependency(parent, [component])
+24 −5
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ SEVERITY_RANKS = [
    DtSeverity("Medium", 3, AnsiColors.YELLOW),
    DtSeverity("Low", 1, AnsiColors.GREEN),
    DtSeverity("Informational", 0, AnsiColors.RESET),
    DtSeverity("Unassigned", 5, AnsiColors.PURPLE)
    DtSeverity("Unassigned", 5, AnsiColors.PURPLE),
]


@@ -225,6 +225,7 @@ class Scanner:
        verify_ssl: bool = True,
        show_findings: bool = False,
        risk_score_threshold: int = -1,
        tags: str = "",
        **_: None,
    ):
        self.base_api_url = base_api_url
@@ -237,7 +238,7 @@ class Scanner:
        self.verify_ssl = verify_ssl
        self.show_findings = show_findings
        self.risk_score_threshold = risk_score_threshold

        self.tags = list(filter(None, map(str.strip, tags.split(",")))) if tags else []
        self.sbom_count = 0
        self.sbom_scan_failed = 0

@@ -413,6 +414,9 @@ class Scanner:
            # add parent UUID to params
            data["parent"] = {"uuid": parent_def.uuid}

        if self.tags:
            data["tags"] = self.tags

        print(
            f"- {AnsiColors.YELLOW}{project_path}{AnsiColors.RESET} not found: create with params {AnsiColors.HGRAY}{json.dumps(data)}{AnsiColors.RESET}..."
        )
@@ -498,6 +502,8 @@ class Scanner:
                    else:
                        params["parentName"] = parent_def.name
                        params["parentVersion"] = parent_def.version
                if self.tags:
                    params["projectTags"] = self.tags

        # publish SBOM
        print(
@@ -506,7 +512,8 @@ class Scanner:
        resp = requests.post(
            f"{self.base_api_url}/v1/bom",
            headers={"X-API-Key": self.api_key, "accept": MIME_APPLICATION_JSON},
            files={"bom": sbom_json, **params},
            files={"bom": sbom_json},
            data=params,
            verify=self.verify_ssl,
        )
        try:
@@ -589,7 +596,7 @@ class Scanner:
                print(
                    f'  - {vuln["vulnId"]} {severity.color}{severity.name}{AnsiColors.RESET}: {component.get("group","")}:{component.get("name")}:{component.get("version","")} - {" ".join(cwes)}'
                )
                print(re.sub('\n+', '\n', vuln.get("description", "").strip()))
                print(re.sub("\n+", "\n", vuln.get("description", "").strip()))
                print()
        if self.risk_score_threshold < 0 or risk_score < self.risk_score_threshold:
            print(
@@ -776,6 +783,13 @@ def run() -> None:
        default=int(os.getenv("DEPTRACK_PURL_MAX_LEN", "-1")),
        help="PURLs max length (-1: auto, 0: no trim, >0: trim to size - default: -1)",
    )
    parser.add_argument(
        "-t",
        "--tags",
        type=str,
        default=os.getenv("DEPTRACK_TAGS", ""),
        help="Comma separated list of tags to attach to the project",
    )
    parser.add_argument(
        "sbom_patterns",
        nargs="*",
@@ -810,6 +824,9 @@ def run() -> None:
    print(
        f"- project path     (--project-path): {AnsiColors.CYAN}{args.project_path}{AnsiColors.RESET}"
    )
    print(
        f"- project tags     (--tags): {AnsiColors.CYAN}{args.tags}{AnsiColors.RESET}"
    )
    print(
        f"- path separator   (--path-separator): {AnsiColors.CYAN}{args.path_separator}{AnsiColors.RESET}"
    )
@@ -849,4 +866,6 @@ def run() -> None:
    )
    print(f"Summary: {scanner.sbom_count} SBOM published")
    if scanner.sbom_count and scanner.sbom_scan_failed:
        fail(f"{scanner.sbom_scan_failed} SBOM scan failed. Check the logs for details.")
        fail(
            f"{scanner.sbom_scan_failed} SBOM scan failed. Check the logs for details."
        )
+1 −1

File changed.

Contains only whitespace changes.