pulumi / pulumi-policy

Pulumi's Policy as Code SDK, CrossGuard. Define infrastructure checks in code to enforce security, compliance, cost, and other practices, enforced at deployment time.
https://www.pulumi.com/docs/guides/crossguard/
Apache License 2.0
32 stars 4 forks source link

Python: Add support for decorators to reduce boilerplate #255

Open justinvp opened 3 years ago

justinvp commented 3 years ago

We should consider adding decorators (e.g. @resource_validation and @stack_validation) that could be applied to functions, to reduce the amount of boilerplate.

@resource_validation
def vanta_tags(args: ResourceValidationArgs, report_violation: ReportViolation):
    """
    Resources must include Vanta tags for bulk tagging inventory.
    """
    ...

Vs the current approach:

def vanta_tags_validator(args: ResourceValidationArgs, report_violation: ReportViolation):
    """
    Resources must include Vanta tags for bulk tagging inventory.
    """
    ...

 vanta_tags_policy = ResourceValidationPolicy(
     name="vanta-tags",
     description=vanta_tags_validator.__doc__.strip(),
     validate=vanta_tags_validator,
 )

The decorator could use the function's __name__ as the default name, if one isn't specified, and use the function's __doc__ as the description, if one isn't specified. Or they can be specified explicitly:

@resource_validation_policy(name="vanta-tags", description="Resources must include Vanta tags for bulk tagging inventory.")
def vanta_tags(args: ResourceValidationArgs, report_violation: ReportViolation):
    ...

The only open question, then, is how to associate these decorated functions with the PolicyPack.

Do we create an ambient PolicyPack instance?

Or maybe you have to create a PolicyPack instance first, and then use decorator functions on that instance on the validation functions? (This might not work, as creating the PolicyPack is what starts the GRPC server).

policy_pack = PolicyPack(
     name="pulumi-internal-policies-python",
     enforcement_level=EnforcementLevel.ADVISORY,
)

@policy_pack.resource_validation
def vanta_tags(args: ResourceValidationArgs, report_violation: ReportViolation):
    """
    Resources must include Vanta tags for bulk tagging inventory.
    """
    ...