2 # Functions for interacting with the routes table in the database
5 from types import StringTypes
9 from PLC.Faults import *
10 from PLC.Parameter import Parameter
11 from PLC.Filter import Filter
12 from PLC.Debug import profile
13 from PLC.Table import Row, Table
14 from PLC.NetworkTypes import NetworkType, NetworkTypes
15 from PLC.NetworkMethods import NetworkMethod, NetworkMethods
16 from PLC.IpAddresses import SimpleAddress, Subnet
21 Representation of a row in the routees table. To use, optionally
22 instantiate with a dict of values. Update as you would a
23 dict. Commit to the database with sync().
27 primary_key = 'route_id'
30 'route_id': Parameter(int, "Route identifier"),
31 'node_id': Parameter(int, "Node this route belongs to"),
32 'subnet': Parameter(str, "Subnet for this route", nullok = True),
33 'next_hop': Parameter(str, "IP address to send outgoing traffic"),
34 'interface_id': Parameter(int, "Interface to send outgoing traffic"),
35 'last_updated': Parameter(int, "Date and time when node entry was created", ro = True),
40 # TODO - validate next_hop and subnet
42 def validate_node_id(self, node_id):
43 nodes = PLC.Nodes.Nodes(self.api, [node_id])
45 raise PLCInvalidArgument, "No such node %d"%node_id
49 def validate_interface_id(self, interface_id):
50 interfaces = PLC.Interfaces.Interfaces(self.api, [interface_id])
52 raise PLCInvalidArgument, "No such interface %d"%interface_id
54 if (interfaces[0]["node_id"] != self["node_id"]):
55 raise PLCInvalidArgument, "Interface is not for the same node as this route"
59 def validate_subnet(self, subnet):
63 def validate_next_hop(self, next_hop):
64 SimpleAddress(next_hop)
69 Flush changes back to the database.
75 validate_last_updated = Row.validate_timestamp
77 def update_timestamp(self, col_name, commit = True):
79 Update col_name field with current time
82 assert 'route_id' in self
83 assert self.table_name
85 self.api.db.do("UPDATE %s SET %s = CURRENT_TIMESTAMP " % (self.table_name, col_name) + \
86 " where route_id = %d" % (self['route_id']) )
89 def update_last_updated(self, commit = True):
90 self.update_timestamp('last_updated', commit)
94 Representation of row(s) from the routees table in the
98 def __init__(self, api, route_filter = None, columns = None):
99 Table.__init__(self, api, Route, columns)
101 # the view that we're selecting upon: start with view_nodes
103 # as many left joins as requested tags
104 for tagname in self.tag_columns:
105 view= "%s left join %s using (%s)"%(view,Route.tagvalue_view_name(tagname),
108 sql = "SELECT %s FROM %s WHERE True" % \
109 (", ".join(self.columns.keys()+self.tag_columns.keys()),view)
111 if route_filter is not None:
112 if isinstance(route_filter, (list, tuple, set)):
113 # Separate the list into integers and strings
114 ints = filter(lambda x: isinstance(x, (int, long)), route_filter)
115 route_filter = Filter(Route.fields, {'route_id': ints})
116 sql += " AND (%s) %s" % route_filter.sql(api, "OR")
117 elif isinstance(route_filter, dict):
118 allowed_fields=dict(Route.fields.items()+Route.tags.items())
119 route_filter = Filter(allowed_fields, route_filter)
120 sql += " AND (%s) %s" % route_filter.sql(api)
121 elif isinstance(route_filter, int):
122 route_filter = Filter(Route.fields, {'route_id': [route_filter]})
123 sql += " AND (%s) %s" % route_filter.sql(api)
125 raise PLCInvalidArgument, "Wrong route filter %r"%route_filter