bring over newinterface branch from Verivue
[plcapi.git] / PLC / Interfaces.py
index f4ddcc8..42e35e5 100644 (file)
@@ -18,49 +18,25 @@ from PLC.NetworkTypes import NetworkType, NetworkTypes
 from PLC.NetworkMethods import NetworkMethod, NetworkMethods
 import PLC.Nodes
 
 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
 
     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.
     """
     """
     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)
 
     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
 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'
 
     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')"),
     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),
         '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"),
         '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"),
         '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),
         }
 
         '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
 
             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
     def validate_mac(self, mac):
         if not mac:
             return mac
@@ -130,19 +89,15 @@ class Interface(Row):
 
         return mac
 
 
         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
 
     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
 
 
         return bwlimit
 
@@ -195,43 +150,6 @@ class Interface(Row):
         assert 'method' in self
         method = self['method']
 
         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):
     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:
             (", ".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)
             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())
                 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, 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
 
             else:
                 raise PLCInvalidArgument, "Wrong interface filter %r"%interface_filter