50 lines
1.7 KiB
Python
50 lines
1.7 KiB
Python
import pandas as pd
|
|
import argparse
|
|
import textwrap
|
|
|
|
def generate_acl_sql(df):
|
|
# Group by schema, table, grantee
|
|
grouped = df.groupby(['table_schema', 'table_name', 'grantee'])['privilege_type'].apply(lambda x: sorted(set(x))).reset_index()
|
|
|
|
lines = []
|
|
lines.append("DO $$")
|
|
lines.append("BEGIN")
|
|
|
|
for _, row in grouped.iterrows():
|
|
schema = row['table_schema']
|
|
table = row['table_name']
|
|
grantee = row['grantee']
|
|
privileges = ", ".join(row['privilege_type'])
|
|
lines.append(f" IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = '{schema}' AND table_name = '{table}') THEN")
|
|
lines.append(f" GRANT {privileges} ON {schema}.{table} TO {grantee};")
|
|
lines.append(" END IF;")
|
|
|
|
lines.append("END")
|
|
lines.append("$$;")
|
|
return "\n".join(lines)
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Generate idempotent ACL SQL with IF statements")
|
|
parser.add_argument('--input', '-i', required=True, help="Path to ACL CSV file")
|
|
parser.add_argument('--output', '-o', default='acl_generated.sql', help="Output SQL file path")
|
|
args = parser.parse_args()
|
|
|
|
# Read ACL CSV
|
|
df = pd.read_csv(args.input)
|
|
|
|
# Expect columns: grantee, table_schema, table_name, privilege_type
|
|
required_cols = {'grantee', 'table_schema', 'table_name', 'privilege_type'}
|
|
if not required_cols.issubset(df.columns):
|
|
raise ValueError(f"Input CSV must contain columns: {', '.join(required_cols)}")
|
|
|
|
sql_script = generate_acl_sql(df)
|
|
|
|
with open(args.output, 'w', encoding='utf-8') as f:
|
|
f.write(sql_script)
|
|
|
|
print(f"✔ ACL idempotent SQL has been generated in {args.output}")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|