macaron.policy_engine package
Submodules
macaron.policy_engine.policy_engine module
This module handles invoking the souffle policy engine on a database.
- macaron.policy_engine.policy_engine.get_generated(database_path)
Get generated souffle code from database specified by configuration.
- Parameters:
database_path (os.PathLike | str) – The path to the database to generate imports and prelude for
- Returns:
A program containing the declarations and relations for the schema of this database
- Return type:
See also
souffle_code_generator.py
- macaron.policy_engine.policy_engine.copy_prelude(database_path, sfl, prelude=None)
Generate and copy the prelude into the souffle instance’s include directory.
- Parameters:
database_path (os.PathLike | str) – The path to the database the facts will be imported from
sfl (SouffleWrapper) – The souffle execution context object
prelude (SouffleProgram | None) – Optional, the prelude to use for the souffle program, if none is given the default prelude is generated from the database at database_path.
- Return type:
- macaron.policy_engine.policy_engine.run_souffle(database_path, policy_content)
Invoke souffle and report result.
- macaron.policy_engine.policy_engine.show_prelude(database_path)
Show the Datalog prelude for a database and exit.
- macaron.policy_engine.policy_engine.run_policy_engine(database_path, policy_content)
Evaluate a policy based on configuration and exit.
macaron.policy_engine.souffle module
Wrapper classes for invoking souffle by subprocess and getting the resulting tables.
Implements a context manager to create and clean up temporary directories.
- exception macaron.policy_engine.souffle.SouffleError(command=None, message='An error occurred with calling Souffle.')
Bases:
Exception
Occurs when the souffle program contains errors, or there is an error invoking souffle.
- __init__(command=None, message='An error occurred with calling Souffle.')
- class macaron.policy_engine.souffle.SouffleWrapper(souffle_full_path='souffle', output_dir=None, include_dir=None, fact_dir=None, library_dir='.')
Bases:
object
Wrapper class for managing the temporary working directory of the souffle interpreter.
Examples
- with SouffleWrapper(fact_dir=”facts”, output_dir=”output”) as sfl:
text = “<souffle program>” result = sfl.interpret_text(text) assert result == {“path”: [[“1”, “2”], [“1”, “3”], [“2”, “3”]]}
- __init__(souffle_full_path='souffle', output_dir=None, include_dir=None, fact_dir=None, library_dir='.')
Create souffle wrapper object.
- Parameters:
souffle_full_path (str) – The path to the souffle executable.
output_dir (str | None) – The path to the souffle program’s output directory.
include_dir (str | None) – The path to the directory to search for files when preprocessing the souffle program #include directives.
fact_dir (str | None) – The path to search for files to import facts from.
library_dir (str) – The path to the directory to search for shared object files when linking souffle functors.
- copy_to_includes(filename, text)
Create a file with in the include directory.
- interpret_file(filename, with_prelude='')
Interpret a file.
- Parameters:
filename (str the file to run.)
with_prelude (str string literal to append to the start of the file before running it.)
- Return type:
- interpret_text(text)
Interpret a string literal.
- Parameters:
text (str string literal to interpret)
- Return type:
macaron.policy_engine.souffle_code_generator module
Generate souffle datalog for policy prelude.
- class macaron.policy_engine.souffle_code_generator.SouffleProgram(declarations=None, directives=None, rules=None)
Bases:
object
Class to store generated souffle datalog program.
- Parameters:
- __init__(declarations=None, directives=None, rules=None)
- update(other)
Merge another program into this one.
- Parameters:
other (SouffleProgram) – The program to merge into self
- Returns:
self, after other has been merged into it
- Return type:
- macaron.policy_engine.souffle_code_generator.column_to_souffle_type(column)
Return a souffle type string for a SQLAlchemy Column.
- Return type:
- macaron.policy_engine.souffle_code_generator.table_to_declaration(table)
Return the souffle datalog declaration for an SQLAlchemy table.
Examples
>>> from sqlalchemy import Column, MetaData, Table >>> from sqlalchemy.sql.sqltypes import Boolean, Integer, String, Text >>> metadata = MetaData() >>> tbl = Table("_example", metadata, Column("id", Integer, nullable=False), Column("hello", String)) >>> assert table_to_declaration(tbl) == '.decl example (id: number, hello: symbol)'
- Parameters:
table (Table) – The sqlalchemy Table to generate a .decl statement for
- Returns:
Datalog declaration corresponding to table
- Return type:
- macaron.policy_engine.souffle_code_generator.get_fact_declarations(metadata)
Get declarations for all mapped tables with names beginning with an underscore and therefore importable by souffle.
- Parameters:
metadata (MetaData) – SqlAlchemy orm metadata object
- Returns:
The set of fact declaration statements, in its declaration field, for all the mapped tables (known to metadata) whose names begin with an ‘_’.
- Return type:
- macaron.policy_engine.souffle_code_generator.get_fact_input_statements(db_name, metadata)
Return a list of input directives for all the mapped tables beginning with an ‘_’.
- Parameters:
db_name (os.PathLike | str) – The database path to import the data from into souffle (absolute path recommended).
metadata (MetaData) – The SQLAlchemy MetaData object containing the table definitions to generate input statements for.
- Returns:
Program containing the set of .input statements, in the directive field, for all tables known to metadata that with an ‘_’.
- Return type:
- macaron.policy_engine.souffle_code_generator.get_souffle_import_prelude(db_name, metadata)
Return souffle datalog code to import all relevant mapped tables.
- Parameters:
db_name (os.PathLike | str) – The path to the database the souffle program will import facts from (absolute path recommended)
metadata (MetaData) – SQLAlchemy MetaData object containing table information
- Return type:
- macaron.policy_engine.souffle_code_generator.project_join_table_souffle_relation(rule_name, left_table, left_common_fields, right_table, right_common_fields, right_ignore_fields, prefix_table_name_to_key=True)
Generate souffle datalog to join two tables together.
This creates a relation that will appear as
- rule_name(left, common, fields, “right_column_name”, right_column_value) :-
left_relation(left, common, _, fields, _), right_relation(right_column_value, _ …).
- rule_name(left, common, fields, “right_column_name_2”, right_column_value) :-
left_relation(left, common, _, fields, _), right_relation(_, right_column_value, …).
- Parameters:
rule_name (str) – The name of the rule to generate
left_table (Table) – The table to appear on the left of the relation (the “subject”)
left_common_fields (dict[str, str]) – The columns to include on the left of the relation, mapped to the names they should have in the declaration
right_table (Table) – The table on the right hand side of the relation (the “predicate”)
right_common_fields (dict[str, str]) – The columns from the right table that should appear on the left of the relation
right_ignore_fields (list[str]) – The columns that should not appear in the relation
prefix_table_name_to_key (bool) – Should the key field of the relation be prefixed with the table name: so that it appears as “tableName.columnName”
- Returns:
- A program containing rules to declare and derive the relations containing the fields:
- (left_common_fields UNION right_common_fields)
PRODUCT ((right_table.columns - right_ignore_fields - right_table.foreign_key_columns) + (foreign_columns where foreign_columns in right_table.foreign_key_columns.tables, and foreign_columns not primary keys))
- Return type:
- macaron.policy_engine.souffle_code_generator.get_table_rules_per_column(rule_name, table, common_fields, ignore_columns)
Generate datalog rules to create subject-predicate relations from a set of columns of a table.
- Parameters:
rule_name (str) – The name of the resulting souffle rule
table (Table) – The sqlalchemy table to read from
common_fields (dict[str, str]) – The table columns to be included in the relation (as the subject) key: the column name value: the corresponding relation field name
ignore_columns (list[str]) – List of column names to be excluded from the relation
- Returns:
- Program to declare and construct the rules
common_fields PRODUCT (table.columns - common_fields - ignore_columns)
- Return type:
- macaron.policy_engine.souffle_code_generator.project_with_fk_join(table)
Create attribute relations joining on foreign keys.
For each foreign key in this table, creates a relation for the reference table which receives this table’s values. See: project_join_table_souffle_relation
- Parameters:
table (Table) – The table to create the projected rules for
- Returns:
The program containing declarations and rules to derive subject-predicate “attribute” relations from the importable tables (tables beginning with ‘_’).
- Return type:
- macaron.policy_engine.souffle_code_generator.project_table_to_key(relation_name, table)
Create rules to convert a table to an attribute that maps its primary keys to its columns.
- Return type:
- macaron.policy_engine.souffle_code_generator.restrict_to_analysis(analyses)
Create relations to restrict the policy analysis to a specific analysis instance (an invocation of souffle).