Changeset 1439
- Timestamp:
- 03/08/07 18:04:18 (6 years ago)
- Files:
-
- 7 added
- 1 edited
-
ccsd/trunk/crcnetd/modules/ccs_billing.py (modified) (3 diffs)
-
ccsweb/trunk/ccs_mods/service/ethernet_customer-ilist.tpl (added)
-
ccsweb/trunk/ccs_mods/service/ethernet_customer-propdetails.tpl (added)
-
ccsweb/trunk/ccs_mods/service/ethernet_customer-props.js (added)
-
ccsweb/trunk/ccs_mods/service/ethernet_customer-props.tpl (added)
-
ccsweb/trunk/ccs_mods/service/ethernet_customer.js (added)
-
ccsweb/trunk/ccs_mods/service/ethernet_customer.php (added)
-
ccsweb/trunk/ccs_mods/service/ethernet_customer.tpl (added)
Legend:
- Unmodified
- Added
- Removed
-
ccsd/trunk/crcnetd/modules/ccs_billing.py
r1432 r1439 33 33 from crcnetd._utils.ccsd_config import config_get, config_getboolean 34 34 from crcnetd.modules.ccs_contact import addContact, editContact 35 from crcnetd._utils.ccsd_service import ccsd_service, ccs_service_error, \ 36 registerService, getServiceInstance 37 38 from crcnetd.modules.ccs_interface import INTERFACE_TYPE_ALIAS, addInterface 39 from crcnetd.modules.ccs_link import ccs_link 35 40 36 41 import calendar … … 56 61 CONNECTION_METHOD_ETHERNET = "Ethernet" 57 62 CONNECTION_METHODS = [ CONNECTION_METHOD_WIRELESS, CONNECTION_METHOD_ETHERNET ] 63 64 # The property name for the link to allocate ethernet customer IPs from 65 ETHERNET_CUSTOMER_LINK_PROPERTY = "ethernet_customer_link" 66 67 # The property name for the firewall class to give to ethernet customers 68 ETHERNET_CUSTOMER_FIREWALL_PROPERTY = "ethernet_customer_firewall" 58 69 59 70 class ccs_billing_error(ccsd_error): … … 1074 1085 1075 1086 ##################################################################### 1087 # Ethernet Customer Service 1088 ##################################################################### 1089 class ethernet_customer_service(ccsd_service): 1090 """Configures customers onto ethernet interfaces""" 1091 1092 serviceName = "ethernet_customer" 1093 allowNewProperties = True 1094 networkService = False 1095 1096 def __init__(self, session_id, service_id): 1097 # Call base class setup 1098 ccsd_service.__init__(self, session_id, service_id) 1099 1100 @exportViaXMLRPC(SESSION_RO, AUTH_ADMINISTRATOR, True, \ 1101 "getEthernetCustomers") 1102 def getCustomers(self): 1103 """Returns a list of customers who receive ethernet services""" 1104 session = getSessionE(self._session_id) 1105 1106 # Get the interface details 1107 res = session.query("SELECT * FROM customers WHERE " \ 1108 "connection_method=%s", (CONNECTION_METHOD_ETHERNET)) 1109 return map(filter_keys, res) 1110 1111 @exportViaXMLRPC(SESSION_RO, AUTH_ADMINISTRATOR, True, \ 1112 "getCustomerInterfaces") 1113 def getInterfaces(self, host_id): 1114 """Returns customer details for the interfaces for the host""" 1115 session = getSessionE(self._session_id) 1116 1117 # Get the interface details 1118 res = session.query("SELECT i.*, ci.contact_id FROM " \ 1119 "interface i LEFT JOIN customer_interface ci ON " \ 1120 "i.interface_id=ci.interface_id WHERE i.host_id=%s", 1121 (host_id)) 1122 1123 # Loop through and collapse alias interfaces into the raw interface 1124 ifaces = {} 1125 tmp = [] 1126 for iface in res: 1127 if iface["contact_id"] == "": 1128 iface["contact_id"] = -1 1129 if iface["interface_type"] == INTERFACE_TYPE_ALIAS: 1130 tmp.append(filter_keys(iface)) 1131 continue 1132 ifaces[iface["name"]] = filter_keys(iface) 1133 ifaces[iface["name"]]["customer"] = None 1134 for iface in tmp: 1135 # Aliases with no associated customer are discarded 1136 if iface["contact_id"] == -1: continue 1137 if ifaces[iface["name"]]["customer"] is not None: 1138 log_warn("Multiple customers assigned to interface %s. " \ 1139 "Ignoring all but the first!" % iface["name"]) 1140 continue 1141 ifaces[iface["name"]]["customer"] = iface 1142 1143 return ifaces 1144 1145 @exportViaXMLRPC(SESSION_RW, AUTH_ADMINISTRATOR, True) 1146 def updateCustomerInterface(self, host_id, interface_id, contact_id): 1147 """Updates the customer that is assigned to the interface 1148 1149 interface_id should be the id for the raw_interface the customer is 1150 assigned to. The actual link record will be created against an alias 1151 interface linked to this raw_interface. 1152 """ 1153 session = getSessionE(self._session_id) 1154 iface = None 1155 host_id = int(host_id) 1156 interface_id = int(interface_id) 1157 contact_id = int(contact_id) 1158 for ifname, temp in self.getInterfaces(host_id).items(): 1159 if temp["interface_id"] == interface_id: 1160 iface = temp 1161 break 1162 if iface is None: 1163 raise ccs_billing_error("Unknown interface") 1164 1165 # Handle removal now 1166 if int(contact_id)==-1: 1167 session.begin("Removing customer from interface '%s'" % \ 1168 (iface["name"])) 1169 try: 1170 # Remove the link 1171 session.execute("DELETE FROM customer_interface WHERE " \ 1172 "interface_id=%s", (iface["customer"]["interface_id"])) 1173 # Remove the alias interface 1174 session.execute("DELETE FROM interface WHERE interface_id=%s", 1175 (iface["customer"]["interface_id"])) 1176 session.commit() 1177 except: 1178 session.rollback() 1179 (etype, value, tb) = sys.exc_info() 1180 log_error("Failed to remove customer: %s" % value, 1181 (etype, value, tb)) 1182 raise ccs_billing_error("Failed to remove customer: %s" % \ 1183 value) 1184 return True 1185 1186 # Get the link to allocate IP address from 1187 values = self.getPropertyValues() 1188 link_id = values[ETHERNET_CUSTOMER_LINK_PROPERTY] 1189 if link_id == -1: 1190 raise ccs_billing_error("No IP link specified. " \ 1191 "Please configure the customer ethernet service!") 1192 1193 # Get the firewall class to use 1194 firewall_class_id = values[ETHERNET_CUSTOMER_FIREWALL_PROPERTY] 1195 if firewall_class_id == -1: 1196 raise ccs_billing_error("No firewall class specified. " \ 1197 "Please configure the customer ethernet service!") 1198 1199 # Validate that the specified customer is allowed to go onto 1200 # an ethernet interface 1201 custc = ccs_customer(self._session_id) 1202 cust = custc.getCustomer(contact_id)[0] 1203 if cust["connection_method"] != CONNECTION_METHOD_ETHERNET: 1204 raise ccs_billing_error("%s is a Wireless customer and " \ 1205 "cannot be assigned to an Ethernet interface!" % \ 1206 cust["username"]) 1207 1208 session.begin("Configured customer '%s' on interface '%s'" % \ 1209 (cust["username"], iface["name"])) 1210 try: 1211 # Create / Find an Alias interface on the specified interface 1212 # for this customers real IP address 1213 alias_id = -1 1214 res = session.query("SELECT i.interface_id, i.ip_address " \ 1215 "FROM interface i LEFT JOIN " \ 1216 "customer_interface ci ON i.interface_id=" \ 1217 "ci.interface_id WHERE i.host_id=%s " \ 1218 "AND i.interface_type=%s AND i.raw_interface=%s", 1219 (host_id, INTERFACE_TYPE_ALIAS, interface_id)) 1220 if len(res) > 0: 1221 link = ccs_link(self._session_id, link_id) 1222 for temp in res: 1223 # Find an existing interface in the right range 1224 if not link.isValidIP(temp["ip_address"]): 1225 continue 1226 alias_id = temp["interface_id"] 1227 break 1228 if alias_id == -1: 1229 # Create a new alias interface 1230 iface={} 1231 iface["interface_type"] = INTERFACE_TYPE_ALIAS 1232 iface["raw_interface"] = interface_id 1233 iface["host_id"] = host_id 1234 iface["link_id"] = link_id 1235 iface["interface_active"] = "t" 1236 iface["bridge_interface"] = "" 1237 iface["alias_netmask"] = "32" 1238 iface["ip_address"] = "" 1239 alias_id = addInterface(self._session_id, iface) 1240 1241 done = False 1242 # Link to the interface 1243 try: 1244 session.execute("INSERT INTO customer_interface (" \ 1245 "contact_id, interface_id) VALUES " \ 1246 "(%s, %s)", (contact_id, alias_id)) 1247 # Success 1248 session.commit() 1249 done = True 1250 except: 1251 (etype, value, tb) = sys.exc_info() 1252 # Assume this is because the record already exists 1253 pass 1254 1255 # Insert failed, try update 1256 if not done: 1257 try: 1258 session.execute("UPDATE customer_interface SET " \ 1259 "contact_id=%s WHERE interface_id=%s", 1260 (contact_id, interface_id)) 1261 except: 1262 # Log the previous error 1263 log_error("Failed to insert customer interface record!", \ 1264 (etype, value, tb)) 1265 # Now log this error 1266 log_error("Failed to update customer interface record!", \ 1267 sys.exc_info()) 1268 1269 # Setup firewall 1270 firewall = getServiceInstance(self._session_id, "firewall") 1271 try: 1272 firewall.addService(host_id) 1273 except: 1274 # Assume due to already existing... 1275 pass 1276 firewall.updateFirewallInterface(host_id, interface_id, \ 1277 firewall_class_id) 1278 1279 # Make permanent and return 1280 session.commit() 1281 return True 1282 except: 1283 session.rollback() 1284 (etype, value, tb) = sys.exc_info() 1285 log_error("Failed to setup customer interface record!", \ 1286 (etype, value, tb)) 1287 raise ccs_billing_error("Exception updating customer interface!") 1288 1289 # Somethign bad happened 1290 return False 1291 1292 def getHostTemplateVariables(self, host_id): 1293 """Returns a dictionary containing template variables for a host 1294 1295 See the getTemplateVariables function for more details. 1296 """ 1297 1298 # Call base class to get the basics 1299 variables = ccsd_service.getHostTemplateVariables(self, host_id) 1300 return variables 1301 1302 @staticmethod 1303 def initialiseService(): 1304 """Called by the system the very first time the service is loaded. 1305 1306 This should setup an entry in the service table and load any default 1307 service properties into the service_prop table. 1308 """ 1309 session = getSessionE(ADMIN_SESSION_ID) 1310 session.begin("Initialising ethernet customer service") 1311 try: 1312 1313 session.execute("INSERT INTO service (service_id, service_name, " \ 1314 "enabled) VALUES (DEFAULT, %s, DEFAULT)", \ 1315 (ethernet_customer_service.serviceName)) 1316 service_id = session.getCountOf("SELECT currval('" \ 1317 "service_service_id_seq') AS service_id", ()) 1318 1319 # Setup the link and firewall properties 1320 session.execute("INSERT INTO service_prop (service_prop_id, " \ 1321 "service_id, prop_name, prop_type, default_value, required) " \ 1322 "VALUES (DEFAULT, %s, %s, 'integer', -1, 't')", \ 1323 (service_id, ETHERNET_CUSTOMER_LINK_PROPERTY)) 1324 session.execute("INSERT INTO service_prop (service_prop_id, " \ 1325 "service_id, prop_name, prop_type, default_value, required) " \ 1326 "VALUES (DEFAULT, %s, %s, 'integer', -1, 't')", \ 1327 (service_id, ETHERNET_CUSTOMER_FIREWALL_PROPERTY)) 1328 1329 # Commit the changese 1330 session.commit() 1331 1332 log_info("Created ethernet customer service entries") 1333 except: 1334 session.rollback() 1335 log_error("Unable to initialise ethernet customer service " \ 1336 "database entries!", sys.exc_info()) 1337 raise ccs_billing_error("Failed to setup database tables!") 1338 1339 return service_id 1340 1341 ##################################################################### 1076 1342 # Module initialisation 1077 1343 ##################################################################### 1078 1344 def ccs_init(): 1079 1345 global invoice_store, billing_template_dir, trml_path, invoice_days_to_pay 1346 1347 # Register the service 1348 registerService(ethernet_customer_service) 1080 1349 1081 1350 # Load the path where we store generated invoices
Note: See TracChangeset
for help on using the changeset viewer.
