X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=PLC%2FInterfaces.py;h=42e35e5410f364506ab0bea44569232ab5d90aec;hb=f1b4415be5ba4be9941d25b531c46696b377fa3a;hp=f4ddcc8ef7c96ba2f63a482afcdec904ecb13a82;hpb=cb77137d884be296fe1e0b15eabe69d18ba443ae;p=plcapi.git diff --git a/PLC/Interfaces.py b/PLC/Interfaces.py index f4ddcc8..42e35e5 100644 --- a/PLC/Interfaces.py +++ b/PLC/Interfaces.py @@ -18,49 +18,25 @@ from PLC.NetworkTypes import NetworkType, NetworkTypes from PLC.NetworkMethods import NetworkMethod, NetworkMethods import PLC.Nodes -def valid_ipv4(ip): +def valid_ip(ip): try: ip = socket.inet_ntoa(socket.inet_aton(ip)) return True except socket.error: return False -def valid_ipv6(ip): - try: - ip = socket.inet_ntop(socket.AF_INET6, socket.inet_pton(socket.AF_INET6, ip)) - return True - except socket.error: - return False - -def valid_ip(ip): - return valid_ipv4(ip) or valid_ipv6(ip) - -def in_same_network_ipv4(address1, address2, netmask): +def in_same_network(address1, address2, netmask): """ Returns True if two IPv4 addresses are in the same network. Faults if an address is invalid. """ + address1 = struct.unpack('>L', socket.inet_aton(address1))[0] address2 = struct.unpack('>L', socket.inet_aton(address2))[0] netmask = struct.unpack('>L', socket.inet_aton(netmask))[0] return (address1 & netmask) == (address2 & netmask) -def in_same_network_ipv6(address1, address2, netmask): - """ - Returns True if two IPv6 addresses are in the same network. Faults - if an address is invalid. - """ - address1 = struct.unpack('>2Q', socket.inet_pton(socket.AF_INET6, address1))[0] - address2 = struct.unpack('>2Q', socket.inet_pton(socket.AF_INET6, address2))[0] - netmask = struct.unpack('>2Q', socket.inet_pton(socket.AF_INET6, netmask))[0] - - return (address1 & netmask) == (address2 & netmask) - -def in_same_network(address1, address2, netmask): - return in_same_network_ipv4(address1, address2, netmask) or \ - in_same_network_ipv6(address1, address2, netmask) - class Interface(Row): """ Representation of a row in the interfaces table. To use, optionally @@ -70,24 +46,18 @@ class Interface(Row): table_name = 'interfaces' primary_key = 'interface_id' - join_tables = ['interface_tag'] + join_tables = ['interface_tag', 'ip_addresses', 'routes'] fields = { 'interface_id': Parameter(int, "Node interface identifier"), 'method': Parameter(str, "Addressing method (e.g., 'static' or 'dhcp')"), - 'type': Parameter(str, "Address type (e.g., 'ipv4')"), - 'ip': Parameter(str, "IP address", nullok = True), 'mac': Parameter(str, "MAC address", nullok = True), - 'gateway': Parameter(str, "IP address of primary gateway", nullok = True), - 'network': Parameter(str, "Subnet address", nullok = True), - 'broadcast': Parameter(str, "Network broadcast address", nullok = True), - 'netmask': Parameter(str, "Subnet mask", nullok = True), - 'dns1': Parameter(str, "IP address of primary DNS server", nullok = True), - 'dns2': Parameter(str, "IP address of secondary DNS server", nullok = True), 'bwlimit': Parameter(int, "Bandwidth limit", min = 0, nullok = True), 'hostname': Parameter(str, "(Optional) Hostname", nullok = True), 'node_id': Parameter(int, "Node associated with this interface"), 'is_primary': Parameter(bool, "Is the primary interface for this node"), + 'if_name': Parameter(str, "Interface name", nullok = True), 'interface_tag_ids' : Parameter([int], "List of interface settings"), + 'ip_address_ids': Parameter([int], "List of addresses"), 'last_updated': Parameter(int, "Date and time when node entry was created", ro = True), } @@ -100,17 +70,6 @@ class Interface(Row): raise PLCInvalidArgument, "Invalid addressing method %s"%method return method - def validate_type(self, type): - network_types = [row['type'] for row in NetworkTypes(self.api)] - if type not in network_types: - raise PLCInvalidArgument, "Invalid address type %s"%type - return type - - def validate_ip(self, ip): - if ip and not valid_ip(ip): - raise PLCInvalidArgument, "Invalid IP address %s"%ip - return ip - def validate_mac(self, mac): if not mac: return mac @@ -130,19 +89,15 @@ class Interface(Row): return mac - validate_gateway = validate_ip - validate_network = validate_ip - validate_broadcast = validate_ip - validate_netmask = validate_ip - validate_dns1 = validate_ip - validate_dns2 = validate_ip - def validate_bwlimit(self, bwlimit): if not bwlimit: return bwlimit - if bwlimit < 500000: - raise PLCInvalidArgument, 'Minimum bw is 500 kbs' + if bwlimit < 1: + raise PLCInvalidArgument, 'Minimum bw is 1 Mbps' + + if bwlimit >= 1000000: + raise PLCInvalidArgument, 'Maximum bw must be less than 1000000' return bwlimit @@ -195,43 +150,6 @@ class Interface(Row): assert 'method' in self method = self['method'] - if method == "proxy" or method == "tap": - if 'mac' in self and self['mac']: - raise PLCInvalidArgument, "For %s method, mac should not be specified" % method - if 'ip' not in self or not self['ip']: - raise PLCInvalidArgument, "For %s method, ip is required" % method - if method == "tap" and ('gateway' not in self or not self['gateway']): - raise PLCInvalidArgument, "For tap method, gateway is required and should be " \ - "the IP address of the node that proxies for this address" - # Should check that the proxy address is reachable, but - # there's no way to tell if the only primary interface is - # DHCP! - - elif method == "static": - for key in ['gateway', 'dns1']: - if key not in self or not self[key]: - if 'is_primary' in self and self['is_primary'] is True: - raise PLCInvalidArgument, "For static method primary network, %s is required" % key - else: - globals()[key] = self[key] - for key in ['ip', 'network', 'broadcast', 'netmask']: - if key not in self or not self[key]: - raise PLCInvalidArgument, "For static method, %s is required" % key - globals()[key] = self[key] - if not in_same_network(ip, network, netmask): - raise PLCInvalidArgument, "IP address %s is inconsistent with network %s/%s" % \ - (ip, network, netmask) - if not in_same_network(broadcast, network, netmask): - raise PLCInvalidArgument, "Broadcast address %s is inconsistent with network %s/%s" % \ - (broadcast, network, netmask) - if 'gateway' in globals() and not in_same_network(ip, gateway, netmask): - raise PLCInvalidArgument, "Gateway %s is not reachable from %s/%s" % \ - (gateway, ip, netmask) - - elif method == "ipmi": - if 'ip' not in self or not self['ip']: - raise PLCInvalidArgument, "For ipmi method, ip is required" - validate_last_updated = Row.validate_timestamp def update_timestamp(self, col_name, commit = True): @@ -276,11 +194,12 @@ class Interfaces(Table): (", ".join(self.columns.keys()+self.tag_columns.keys()),view) if interface_filter is not None: + # TODO: Deleted the ability here to filter by ipaddress; Need to make + # sure that wasn't used anywhere. if isinstance(interface_filter, (list, tuple, set)): # Separate the list into integers and strings ints = filter(lambda x: isinstance(x, (int, long)), interface_filter) - strs = filter(lambda x: isinstance(x, StringTypes), interface_filter) - interface_filter = Filter(Interface.fields, {'interface_id': ints, 'ip': strs}) + interface_filter = Filter(Interface.fields, {'interface_id': ints}) sql += " AND (%s) %s" % interface_filter.sql(api, "OR") elif isinstance(interface_filter, dict): allowed_fields=dict(Interface.fields.items()+Interface.tags.items()) @@ -289,9 +208,6 @@ class Interfaces(Table): elif isinstance(interface_filter, int): interface_filter = Filter(Interface.fields, {'interface_id': [interface_filter]}) sql += " AND (%s) %s" % interface_filter.sql(api) - elif isinstance (interface_filter, StringTypes): - interface_filter = Filter(Interface.fields, {'ip':[interface_filter]}) - sql += " AND (%s) %s" % interface_filter.sql(api, "AND") else: raise PLCInvalidArgument, "Wrong interface filter %r"%interface_filter