(no commit message)
[sfa.git] / sfatables / sfatables
1 #!/usr/bin/python 
2 # SFAtables is a tool for restricting access to an SFA aggregate in a generic
3 # and extensible way. 
4
5 # It is modeled using abstractions in iptables. Specifically, 'matches' specify
6 # criteria for matching certain requests, 'targets' specify actions that treat
7 # requests in a certain way, and 'chains' are used to group related
8 # match-action pairs.
9
10 import sys
11 import os
12 import pdb
13 from optparse import OptionParser
14
15 from sfatables import commands, matches, targets
16
17 def load_extensions(module, list):
18     command_dict={}
19
20     for command_name in list:
21         command_module = __import__(".".join([module,command_name]),fromlist=[module])
22         command = getattr(command_module, command_name)
23         command_dict[command_name]=command()
24
25     return command_dict
26
27 def create_parser(command_dict):
28     parser = OptionParser(usage="sfatables [command] [chain] [match] [target]",
29                              description='See "man sfatables" for more detail.')
30     
31     for k in command_dict.keys():
32         command = command_dict[k]
33         for (short_option,long_option) in command.options:
34             parser.add_option(short_option,long_option,dest=command.type,action=command.action,const=k,help=command.help,metavar="CHAIN")
35
36     return parser
37
38
39 def partition(sep, lst):
40     ret = []
41     curpart = []
42     for item in lst:
43         if (item==sep):
44             ret.append(curpart)
45             curpart=[]
46         else:
47             curpart.append(item)
48     ret.append(curpart)
49
50     return ret
51
52
53 def main():
54     # Segment command line into three blobs, one each for the command, match and target respectively.
55     
56     pargs = partition('--', sys.argv[1:])
57
58     command_dict = load_extensions("sfatables.commands",commands.all)
59     command_parser = create_parser(command_dict)
60     (options, args) = command_parser.parse_args()
61
62     command = command_dict[options.command]
63
64     if (command.matches):
65         if (len(pargs)<2):
66             raise Exception("Must specify match for this command")
67         match_dict = load_extensions("sfatables.matches",matches.all)
68         match_parser = create_parser(match_dict)
69         (match_options, args) = match_parser.parse_args(pargs[1])
70     else:
71         match_options=None
72
73     if (command.targets):
74         if (len(pargs)<3):
75             raise Exception("Must specify a target for this command")
76         match_dict = load_extensions("sfatables.targets",targets.all)
77         target_parser = create_parser(match_dict)
78         (target_options, args) = target_parser.parse_args(pargs[2])
79     else:
80         target_options = None
81
82     command(options, match_options, target_options)
83
84 if __name__=='__main__':
85     main()