Skip to content
This repository has been archived by the owner on Feb 2, 2023. It is now read-only.

Commit

Permalink
Merge pull request #6 from cisagov/improvement/add_owner_field_to_yaml
Browse files Browse the repository at this point in the history
Replace individual `reporter` keys with a document top-level `owners` key
  • Loading branch information
mcdonnnj committed Jan 7, 2022
2 parents 24ea411 + c498ebd commit fd51f18
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 16 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ The common YAML format looks like this:
```yaml
---
version: '1.0'
owners:
- name: cisagov
url: https://github.com/cisagov/log4j-affected-db
software:
- cves:
- affected_versions:
Expand All @@ -37,15 +40,14 @@ software:
- 1.2
investigated: true
unaffected_versions: []
last_updated: "2021-12-09"
notes: Blah blah blah
product: ProductA
references:
- https://www.reddit.com/r/Vendor1/comments/abcdef/log4j
reporter: cisagov
vendor: Vendor1
vendor_links:
- https://vendor1.com/discussion/comment/622612/#Comment_622612
last_updated: "2021-12-09"
...
```
Expand Down
12 changes: 10 additions & 2 deletions src/mdyml/convert_cisagov.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ def convert() -> None:

out_dict["notes"] = in_row_dict["notes"]
out_dict["references"] = [in_row_dict["references"]]
out_dict["reporter"] = "cisagov"
# Parse the existing date, or not
if parsed_date := dateparser.parse(in_row_dict["last_updated"]):
# Check if parsed date has a timezone
Expand Down Expand Up @@ -178,7 +177,16 @@ def convert() -> None:
filename = SOFTWARE_LIST_FILE_FORMAT.format(key)
logging.debug("Writing data for '%s' to '%s'", key, filename)
with open(filename, "w") as out_file:
doc = {"version": "1.0", "software": data}
doc = {
"version": "1.0",
"owners": [
{
"name": "cisagov",
"url": "https://github.com/cisagov/log4j-affected-db",
}
],
"software": data,
}

yaml = ruamel.yaml.YAML()
yaml.indent(mapping=2, offset=2, sequence=4)
Expand Down
39 changes: 28 additions & 11 deletions src/yml/normalize_yml.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,27 +34,39 @@
from . import __version__

Software = list[dict[str, Any]]
Owners = list[dict[str, str]]
YamlData = dict[str, Software | Owners]


def munge(filenames: list[str]) -> Software:
"""Munge together the "software" nodes from YAML files into a single Python dictionary."""
def munge(filenames: list[str], canonical=False) -> YamlData:
"""Munge together the "owners" and "software" nodes from YAML files into a single Python dictionary."""
ans = []
owners = []
for filename in filenames:
with open(filename, "r") as f:
ans.extend(yaml.safe_load(f)["software"])
loaded_data = yaml.safe_load(f)
if "owners" in loaded_data:
owners.extend(loaded_data["owners"])
if not canonical:
for product in loaded_data["software"]:
product["reporter"] = loaded_data.get("owners", [])
ans.extend(loaded_data["software"])

return ans
# De-duplicate owner information
owners = list({i["name"] + i["url"]: i for i in owners}.values())

return {"owners": owners, "software": ans}

def normalize(software: Software) -> Software:

def normalize(data: YamlData) -> YamlData:
"""Normalize the software entries."""
return software
return data


def sort(software: Software) -> Software:
def sort(data: YamlData) -> YamlData:
"""Sort the software entries."""
software.sort(key=lambda x: (x["vendor"] + x["product"]).lower())
return software
data["software"].sort(key=lambda x: (x["vendor"] + x["product"]).lower())
return data


def main() -> None:
Expand Down Expand Up @@ -91,12 +103,17 @@ def main() -> None:

# Do that voodoo that you do so well...
if validated_args["--cisagov-format"]:
data: YamlData = sort(
normalize(munge(validated_args["<yml_file>"], canonical=True))
)
doc = {
"version": "1.0",
"software": sort(normalize(munge(validated_args["<yml_file>"]))),
"owners": data["owners"],
"software": data["software"],
}
else:
doc = sort(normalize(munge(validated_args["<yml_file>"])))
data: YamlData = sort(normalize(munge(validated_args["<yml_file>"])))
doc = data["software"]

yml = ruamel.yaml.YAML()
yml.indent(mapping=2, offset=2, sequence=4)
Expand Down
4 changes: 3 additions & 1 deletion src/ymlmd/yml2md.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ def generate_markdown(software: Software) -> None:
),
notes=s["notes"],
references="; ".join([x for x in s["references"] if len(x) != 0]),
reporter=s["reporter"],
reporter=", ".join(
f"[{i['name']}]({i['url']})" for i in s["reporter"]
),
# create a datetime from string and print date portion
last_updated=dateparser.parse(s["last_updated"]).strftime(
"%Y-%m-%d"
Expand Down

0 comments on commit fd51f18

Please sign in to comment.