Skip to content

Commit

Permalink
Update guard hook (#251)
Browse files Browse the repository at this point in the history
* Update guard hook
  • Loading branch information
kddejong authored Oct 20, 2023
1 parent 51208e8 commit 300f56e
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 28 deletions.
6 changes: 4 additions & 2 deletions packages/cfn_guard_rs/python/cfn_guard_rs/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,12 @@ def run_checks(data: dict, rules: str) -> FileReport:
"""
try:
raw_output = run_checks_rs(json.dumps(data), rules, False)
LOG.debug("Raw output: %s", raw_output)
output = json.loads(raw_output)

return FileReport.from_object(output)
except json.JSONDecodeError as err:
LOG.debug(
LOG.info(
"JSON decoding error when processing return value [%s] got error: %s",
raw_output,
err,
Expand All @@ -55,9 +56,10 @@ def run_checks(data: dict, rules: str) -> FileReport:
except CfnGuardParseError as err:
raise errors.ParseError(str(err))
except Exception as err:
LOG.debug(
LOG.info(
"Received unknown exception [%s] while running checks, got error: %s",
type(err),
err,
exc_info=True,
)
raise errors.UnknownError(str(err))
60 changes: 39 additions & 21 deletions packages/cfn_guard_rs/python/cfn_guard_rs/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ class Messages:
error_message: str | None = field(default=None)

@classmethod
def from_object(cls, obj) -> "Messages":
def from_object(cls, obj) -> "Messages" | None:
if obj is None:
return None

return cls(
custom_message=obj.get("custom_message"),
error_message=obj.get("error_message"),
Expand All @@ -49,7 +52,7 @@ class RuleReport:

name: str = field()
metadata: Dict[str, Any] = field()
messages: Messages = field()
messages: Messages | None = field()
checks: Sequence[ClauseReport] = field()

@classmethod
Expand All @@ -70,11 +73,11 @@ class GuardBlockReport(ValueComparisons):
"""Guard Block Report"""

context: str = field()
messages: Messages = field()
messages: Messages | None = field()
unresolved: Any = field()

@classmethod
def from_object(cls, obj):
def from_object(cls, obj) -> "GuardBlockReport" | None:
if obj is None:
return obj

Expand All @@ -97,10 +100,10 @@ def value_to(self) -> Any:
class DisjunctionsReport:
"""Disjunctions"""

checks: ClauseReport = field()
checks: ClauseReport | None = field()

@classmethod
def from_object(cls, obj):
def from_object(cls, obj) -> "DisjunctionsReport" | None:
if obj is None:
return obj

Expand All @@ -112,10 +115,13 @@ class UnaryComparison:
"""Unary Comparison"""

value: Any = field()
comparison: Tuple[str, bool] = field()
comparison: Tuple[Any, ...] | None = field()

@classmethod
def from_object(cls, obj):
def from_object(cls, obj) -> "UnaryComparison" | None:
if obj is None:
return None

return cls(
value=obj.get("value"),
comparison=tuple(obj.get("comparison")),
Expand All @@ -131,7 +137,7 @@ class UnResolved:
reason: Any = field()

@classmethod
def from_object(cls, obj):
def from_object(cls, obj) -> "UnResolved" | None:
if obj is None:
return None
return cls(
Expand All @@ -147,7 +153,10 @@ class ValueUnResolved:
comparison: Any = field()

@classmethod
def from_object(cls, obj):
def from_object(cls, obj) -> "ValueUnResolved" | None:
if obj is None:
return None

return cls(
value=obj.get("value"),
comparison=obj.get("comparison"),
Expand All @@ -163,7 +172,7 @@ class UnaryCheck(ValueComparisons):
UnresolvedContext: Any | None = field(default=None)

@classmethod
def from_object(cls, obj):
def from_object(cls, obj) -> "UnaryCheck" | None:
if obj is None:
return obj

Expand Down Expand Up @@ -191,11 +200,11 @@ class UnaryReport:
"""Unary Report"""

context: str = field()
messages: Messages = field()
check: UnaryCheck = field()
messages: Messages | None = field()
check: UnaryCheck | None = field()

@classmethod
def from_object(cls, obj):
def from_object(cls, obj) -> "UnaryReport" | None:
if obj is None:
return None

Expand All @@ -213,7 +222,7 @@ class BinaryComparison:
comparison: Any = field()

@classmethod
def from_object(cls, obj):
def from_object(cls, obj) -> "BinaryComparison" | None:
if obj is None:
return None
return cls(
Expand All @@ -230,6 +239,9 @@ def __init__(self, **kwargs) -> None:

@classmethod
def from_object(cls, obj) -> "InComparison" | None:
if obj is None:
return None

return cls(
from_=obj.get("from"),
to_=obj.get("to"),
Expand All @@ -244,7 +256,10 @@ class BinaryCheck(ValueComparisons):
InResolved: Any = field(default=None)

@classmethod
def from_object(cls, obj):
def from_object(cls, obj) -> "BinaryCheck" | None:
if obj is None:
return None

return cls(
Resolved=BinaryComparison.from_object(obj.get("Resolved")),
UnResolved=UnResolved.from_object(obj.get("UnResolved")),
Expand All @@ -271,11 +286,11 @@ def value_to(self) -> Any:
@dataclass(eq=True, frozen=True)
class BinaryReport:
context: str = field()
messages: Messages = field()
check: BinaryCheck = field()
messages: Messages | None = field()
check: BinaryCheck | None = field()

@classmethod
def from_object(cls, obj):
def from_object(cls, obj) -> "BinaryReport" | None:
if obj is None:
return obj
return cls(
Expand All @@ -293,7 +308,7 @@ class GuardClauseReport(ValueComparisons):
Binary: BinaryReport | None = field(default=None)

@classmethod
def from_object(cls, obj):
def from_object(cls, obj) -> "GuardClauseReport" | None:
if obj is None:
return obj

Expand Down Expand Up @@ -345,7 +360,10 @@ class ClauseReport(ValueComparisons):
Clause: GuardClauseReport | None = field(default=None)

@classmethod
def from_object(cls, obj):
def from_object(cls, obj) -> "ClauseReport" | None:
if obj is None:
return None

return cls(
Rule=RuleReport.from_object(obj.get("Rule")),
Disjunctions=DisjunctionsReport.from_object(obj.get("Disjunctions")),
Expand Down
18 changes: 13 additions & 5 deletions packages/cfn_guard_rs_hook/cfn_guard_rs_hook/guard_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,20 +284,28 @@ def __run_checks(self, template: dict, type_configuration: Any) -> ProgressEvent
progress.errorCode = HandlerErrorCode.NonCompliant
progress.message = ""
for not_compliant in guard_result.not_compliant:
LOG.debug("Not Compliant: %s", not_compliant)
rule = not_compliant.Rule
if rule is None:
progress.message += "Found not compliant without rule. "
continue
for err in rule.checks:
path = err.value_from.get("path")
LOG.debug("Rule check: %s", err)
clause = err.Clause
if clause is None:
progress.message += "Found not compliant without a clause. "
continue
progress.message += (
f"Rule [{rule.name}] failed on "
f"property [{path}] and got error [{clause.messages}]. "
)
if err.value_from:
progress.message += (
f"Rule [{rule.name}] failed on "
f"property [{err.value_from.get('path')}] "
f"and got error [{clause.messages}]. "
)
else:
progress.message += (
f"Rule [{rule.name}] failed "
f"with error [{clause.messages}]. "
)
progress.message = progress.message.strip()
LOG.debug("Progress Event: %s", progress)
return progress

0 comments on commit 300f56e

Please sign in to comment.