Skip to content

Commit 23cd836

Browse files
authored
[fixlib][feat] Define separate assessment section (#2257)
1 parent d77c65c commit 23cd836

2 files changed

Lines changed: 36 additions & 5 deletions

File tree

fixlib/fixlib/baseresources.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,22 @@
44
import hashlib
55
import weakref
66
from abc import ABC, abstractmethod
7+
from collections import defaultdict
78
from copy import deepcopy
8-
from datetime import datetime, timezone, timedelta
9+
from datetime import datetime, timedelta
910
from enum import Enum, StrEnum, unique
1011
from functools import wraps, cached_property
1112
from typing import Dict, Iterator, List, ClassVar, Optional, TypedDict, Any, TypeVar, Type, Callable, Set, Tuple
12-
from collections import defaultdict
1313

1414
from attr import resolve_types
1515
from attrs import define, field, Factory, frozen, evolve
1616
from prometheus_client import Counter, Summary
1717

18+
from fixlib.basecategories import Category
1819
from fixlib.json import from_json as _from_json, to_json as _to_json, to_json_str
1920
from fixlib.logger import log
2021
from fixlib.types import Json
2122
from fixlib.utils import make_valid_timestamp, utc_str, utc
22-
from fixlib.basecategories import Category
23-
2423

2524
metrics_resource_pre_cleanup_exceptions = Counter(
2625
"resource_pre_cleanup_exceptions_total",
@@ -246,6 +245,32 @@ def __str__(self) -> str:
246245
MetricNameWithUnit = str
247246

248247

248+
class Severity(StrEnum):
249+
info = "info"
250+
low = "low"
251+
medium = "medium"
252+
high = "high"
253+
critical = "critical"
254+
255+
256+
@define(slots=True)
257+
class Finding:
258+
title: str
259+
severity: Severity = Severity.medium
260+
description: Optional[str] = None
261+
remediation: Optional[str] = None
262+
created_at: Optional[datetime] = None
263+
details: Optional[Json] = None
264+
265+
266+
@define(slots=True)
267+
class Assessment:
268+
# The provider of the security assessment
269+
provider: str
270+
# All findings of the security provider to this resource
271+
findings: List[Finding] = field(factory=list)
272+
273+
249274
@define(eq=False, slots=False, kw_only=True)
250275
class BaseResource(ABC):
251276
"""
@@ -305,6 +330,8 @@ class BaseResource(ABC):
305330
_resource_usage: Dict[MetricNameWithUnit, Dict[str, float]] = field(factory=lambda: defaultdict(dict))
306331
# Deep link into the cloud provider's console
307332
_provider_link: Optional[str] = None
333+
# Assessment details for this resource: multiple providers can append their findings
334+
_assessments: List[Assessment] = field(factory=list)
308335

309336
ctime: Optional[datetime] = field(
310337
default=None,

fixlib/fixlib/core/model_export.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from attrs import Attribute
1313

1414
from fixlib.baseresources import BaseResource
15-
from fixlib.json import from_json
15+
from fixlib.json import from_json, to_json
1616
from fixlib.types import Json
1717
from fixlib.utils import type_str
1818

@@ -85,6 +85,8 @@ def check(to_check: type) -> None:
8585
for subclass in clazz.__subclasses__():
8686
check(subclass)
8787
for field in attrs.fields(clazz):
88+
if field.name.startswith("_"): # ignore private properties
89+
continue
8890
check(field.type)
8991
elif is_enum(clazz):
9092
all_classes.add(clazz)
@@ -349,6 +351,8 @@ def node_to_dict(node: BaseResource, changes_only: bool = False, include_revisio
349351
metadata["protected"] = True
350352
if link := node._provider_link:
351353
metadata["provider_link"] = link
354+
if assessments := node._assessments:
355+
metadata["assessments"] = to_json(assessments)
352356

353357
node_dict["reported"] = get_node_attributes(node)
354358
node_dict["metadata"] = metadata

0 commit comments

Comments
 (0)