#!/usr/bin/env python3
# encoding: utf-8
# api: python
# description: extract crsvars.conf plugin meta data struct
import re, json
from collections import OrderedDict
src1 = open("./dev/crsvars.conf", "r").read()
# out
pmd1 = OrderedDict()
# read from sample .conf
rx1 = re.compile("""
(
(?: ^\# .* \\n )+
)
^SecAction \s+[\\\\]?\s*
\" ([^\"]+) \"
""", re.X|re.M|re.I)
for doc, actions in rx1.findall(src1):
#print("D=",doc, " A=",actions)
doc = re.sub("^\#\s+", "", doc, 0, re.M).strip()
desc = re.findall("^(\w+.*)", doc, re.M)[0]
id = re.findall("id:(\d+)", actions)[0]
# iterate over multiple setvar:
for var,val in re.findall("setvar:'?([\w\.\-]+)=([^\"\'\\\\]+),?'?", actions):
#print("V=",var, " L=", val)
p = {
"id": id,
"name": var,
"description": desc,
"type": "str",
"value": val.strip(","), # ← let's keep default values here (might strip it in dialog)
"help": doc
}
if re.search("anomaly_score|paranoia_level", var):
p["type"] = "select"
p["select"] = "0=0 (off)|1=1 (standard)|2=2 (extended)|3=3 (excessive)|4=4 (banking sector)|5=5 (absurd)"
if var == "id":
p["type"] = "select"
p["select"] = "5999=5999|900999=900999"
elif re.search("tx\.(block_|crs_excl|enforce_|do_|crs_validate|blocking_early)", var): # re.match("^[01]$", val) or re
p["type"] = "bool"
elif len(p["value"]) >= 50:
p["type"] = "text"
pmd1[p["name"]] = p
# postprocess
for name,p in pmd1.items():
if "select" in p:
kv = p["select"].split("|")
kv = [v.split("=", 2) for v in kv]
p["select"] = dict(kv)
#std
#print(json.dumps(pmd, indent=4))
# write as ordereddict
print("setvar = OrderedDict()")
for k,d in pmd1.items():
print(f"setvar['{k}'] = " + json.dumps(d, indent=4))
#print(len(pmd2))