Skip to content

Commit

Permalink
Merge pull request #85 from Skyscanner/improve_source_inlining
Browse files Browse the repository at this point in the history
Improve source inlining
  • Loading branch information
IgnacioRV committed Dec 13, 2019
2 parents 7cd15dc + 56393d8 commit 8337ed0
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 20 deletions.
23 changes: 23 additions & 0 deletions docs/macros.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import importlib
import inspect

from cfripper import rules
Expand All @@ -16,3 +17,25 @@ def cfripper_rules():
else:
results.append((klass.__name__, None))
return sorted(results)

@env.macro
def inline_source(reference):
obj = get_object_from_reference(reference)
source = "".join(inspect.getsourcelines(obj)[0])
return f"```python3\n{source}```"


def get_object_from_reference(reference):
split = reference.split(".")
right = []
module = None
while split:
try:
module = importlib.import_module(".".join(split))
break
except ModuleNotFoundError:
right.append(split.pop())
if module:
for entry in reversed(right):
module = getattr(module, entry)
return module
24 changes: 4 additions & 20 deletions docs/rules.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
## Available Rules
{% for rule in cfripper_rules()-%}
{% if rule.1 -%}
#### {{ rule.0 }}
{% if rule.1 -%}
{{ rule.1 }}
{% else -%}
#### {{ rule.0 }}
{% endif -%}
{% endfor %}

Expand All @@ -14,28 +12,14 @@
To add custom rules first extend the [Rule](https://github.com/Skyscanner/cfripper/blob/master/cfripper/model/rule.py)
class. Then implement the `invoke` method by adding your logic.

```python
@abstractmethod
def invoke(self, cfmodel: CFModel):
pass
```
{{ inline_source('cfripper.model.rule.Rule.invoke') }}

CFripper uses [pycfmodel](https://github.com/Skyscanner/pycfmodel) to create a Python model of the CloudFormation script.
This model is passed to the `invoke` function as the `resources` parameter. You can use the model's iterate through the
This model is passed to the `invoke` function as the `cfmodel` parameter. You can use the model's iterate through the
resources and other objects of the model and use the helper functions to perform various checks. Look at the
[current rules](cfripper/rules) for examples.

```python
class S3CrossAccountTrustRule(CrossAccountCheckingRule):

REASON = "{} has forbidden cross-account policy allow with {} for an S3 bucket."

def invoke(self, cfmodel):
for logical_id, resource in cfmodel.Resources.items():
if isinstance(resource, S3BucketPolicy):
for statement in resource.Properties.PolicyDocument._statement_as_list():
self._do_statement_check(logical_id, statement)
```
{{ inline_source('cfripper.rules.cross_account_trust.S3CrossAccountTrustRule') }}

## Monitor Mode
By default, each rule has `MONITOR_MODE` set to false. Monitor model will return the failed rules in another field in the
Expand Down

0 comments on commit 8337ed0

Please sign in to comment.