% vim set ft=prolog % rule(src, dst, proto, port, source(..)). :- module(firewall, [ %fw_rule/2, warning/1, retract_all_from/1]). :- use_module(library(assoc)). :- use_module(library(files)). :- use_module(library(format)). :- use_module(library(dcgs)). :- use_module(library(lists)). :- use_module(library(serialization/json)). :- use_module(hosts, [ router_link/3]). :- dynamic(fw_rule/2). warning(Msg) :- fw_rule(Host, Attr), \+ get_assoc("from", Attr, _), format("Missing 'from' on fw_rule for host '~w', ~w", [Host, Attr], Msg). rules_from(From, Rules) :- findall( fw_rule(H, Attr), ( fw_rule(H, Attr), get_assoc("from", Attr, From) ), Rules). retract_all_from(From) :- rules_from(From, Rules), retract_rules(Rules). retract_rules([R|Rules]) :- retract(R), retract_rules(Rules). retract_rules([]). ansible(Basedir) :- setof(Host, Attrs^fw_rule(Host, Attrs), Hosts), ansible_host(Basedir, Hosts). ansible_host(Basedir, [Host|Hosts]) :- atom_chars(Host, HostS), append(Basedir, [HostS], DirPs), path_segments(Dir, DirPs), append(Basedir, [HostS, "firewall.yaml"], FilePs), path_segments(File, FilePs), format("mkdir ~s~n", [Dir]), make_directory_path(Dir), format("firewall: ~s~n", [File]), ansible_firewall(File, Host), ansible_host(Basedir, Hosts). ansible_firewall(File, Host) :- true.