Exemple #1
0
    def updateDetails(self, details):
        """Updates the details of the interface.

        details should be a dictionary containing only those parameters
        that have changed and need to be updated in the database.

        Returns ccs_interface.SUCCESS,
        """
        session = getSessionE(self._session_id)

        # Check the data
        validateInterface(self._session_id, details)
       
        # Extract values for ease of use.
        host_id = "host_id" in details.keys() and \
                int(details["host_id"]) or self["host_id"]
        link_id = "link_id" in details.keys() and \
                int(details["link_id"]) or self["link_id"]
        subasset_id = "subasset_id" in details.keys() and \
                int(details["subasset_id"]) or self["subasset_id"]
        interface_type =  "interface_type" in details.keys() and \
                int(details["interface_type"]) or self["interface_type"]
        bridge_interface = "bridge_interface" in details.keys() and \
                int(details["bridge_interface"]) or self["bridge_interface"]
        monitor_interface = "monitor_interface" in details.keys() and \
                details["monitor_interface"] or self["monitor_interface"]
    
        # Check subasset is valid if it is specified
        if subasset_id != self["subasset_id"] and subasset_id != -1:
            subasset = ccs_subasset(self._session_id, subasset_id)
            if not subasset.supportsFunction("interface"):
                raise ccs_interface_error("Invalid subasset type!")
            if not subasset.availableForInterface(host_id):
                raise ccs_interface_error("Subasset already in use!")
        
        # Check this host doesn't already have an interface on the new link
        if link_id != self["link_id"] and \
                (bridge_interface=="" or bridge_interface==-1):
            link = ccs_link(self._session_id, link_id)
            if link.connectsHost(host_id, self.interface_id):
                raise ccs_interface_error("Host already has an interface on " \
                        "the specified link!")
            if "ip_address" not in details.keys():
                raise ccs_interface_error("IP Address must change when " \
                        "modifing the link!")
                
        # Check interface type
        if interface_type != self["interface_type"]:
            if interface_type <= INTERFACE_TYPE_MIN or \
                    interface_type >= INTERFACE_TYPE_MAX:
                raise ccs_interface_error("Invalid interface type!")
    
        # Check IP is specified and is correct for the link
        if "ip_address" in details.keys() and \
                (bridge_interface=="" or bridge_interface==-1):
            link = ccs_link(self._session_id, link_id)
            if details["ip_address"] == "":
                details["ip_address"] = link.allocateIP(host_id, False)
            elif not link.isValidIP(details["ip_address"]):
                raise ccs_interface_error("Invalid IP address for link!")
        
        # Check interface is in master mode if a channel was specified
        if "master_channel" in details.keys() or \
                "master_mode" in details.keys():
            if "master_interface" not in details.keys():
                if not self._properties["master_interface"]:
                    log_warn("Interface channel may only " \
                            "be set for Master mode interfaces!")
                del details["master_channel"]
                del details["master_mode"]
            else:
                if details["master_interface"]!="t":
                    log_warn("Interface channel may only " \
                            "be set for Master mode interfaces!")
                    del details["master_channel"]
                    del details["master_mode"]

        # Check VLAN properties
        if interface_type == INTERFACE_TYPE_VLAN:
            # Check the vid is valid if specified
            if "vid" in interface.keys() and \
                    interface["vid"] != "":
                try:
                    vid = int(interface["vid"])
                except:
                    raise ccs_interface_error("Alias VLAN ID must be an integer")
            # VLAN interfaces have a name derived from their parent interface
            parent_iface = ccs_interface(session_id, interface["raw_interface"])
            interface["name"] = "%s.%s" % \
                    (parent_iface["name"], interface["vid"])

        # Check alias properties
        if interface_type == INTERFACE_TYPE_ALIAS:
            # Check the netmask is valid if specified
            if "alias_netmask" in details.keys() and \
                    details["alias_netmask"] != "":
                if details["alias_netmask"].startswith("/"):
                    details["alias_netmask"] = details["alias_netmask"][1:]
                try:
                    details["alias_netmask"] = int(details["alias_netmask"])
                except:
                    raise ccs_interface_error("Alias netmask must be an integer")
            # Alias interfaces have a name derived from their parent interface
            parent_iface = ccs_interface(self._session_id, 
                    details["raw_interface"])
            details["name"] = "%s-alias-%s" % (parent_iface["name"], link_id)
            details["ifname"] = details["name"]

        # Deal with ifname/name dictionary entries
        if "ifname" in details.keys():
            details["name"] = details["ifname"]
        
        # Wrap changes into a changeset
        self._forceChangeset("Interface details updated")     

        # Deal with subasset changes
        if subasset_id != self["subasset_id"] and \
                interface_type != INTERFACE_TYPE_VAP:
            if self.hasSubasset():
                self.detachSubasset()
            subasset = ccs_subasset(self._session_id, subasset_id)
            from ccs_host import ccs_host
            host = ccs_host(self._session_id, host_id)
            if host.hasAsset():
                subasset.attachTo(host["asset_id"])
            elif host.hasSite():
                subasset.moveToSite(host["site_id"])
            
        # Build list of properties for the interface type
        props = [ "interface_id", "interface_type", "host_id", "link_id", \
                "name", "use_gateway", "interface_active", "master_mode", \
                "master_interface", "master_channel", "module_id", \
                "monitor_interface" ]
        nProps = []
        if interface_type == INTERFACE_TYPE_PHYSICAL or \
                interface_type == INTERFACE_TYPE_VAP:
            props.extend(["subasset_id"])
            nProps.extend(["raw_interface", "alias_netmask"])
        elif interface_type == INTERFACE_TYPE_VLAN:
            props.extend(["raw_interface", "vid"])
            nProps.extend(["subasset_id", "alias_netmask"])            
        elif interface_type == INTERFACE_TYPE_ALIAS:
            props.extend(["raw_interface",])
            nProps.extend(["subasset_id"])
            if "alias_netmask" in details.keys() and \
                    details["alias_netmask"] != "":
                props.extend(["alias_netmask"])
        if monitor_interface=="t":
            nProps.extend(["ip_address", "bridge_interface"])
        elif bridge_interface != "" and bridge_interface!=-1:
            props.extend(["bridge_interface"])
            nProps.extend(["ip_address"])
        else:
            props.extend(["ip_address"])
            nProps.extend(["bridge_interface"])
        
        # Build update string
        (sql, values) = buildUpdateFromDict("interface", props, details, \
                "interface_id", self.interface_id, True, nProps)                
        if values is None:
            # No changes made... ?
            return self.returnSuccess()
        
        # Run the query
        session.execute(sql, values)
        
        # Fire the trigger
        triggerHostEvent(self._session_id, "interfaceModified", host_id, \
                interface_id=self.interface_id);
        
        return self.returnSuccess()
Exemple #2
0
def addInterface(session_id, interface):
    """Creates a new interface on a host
    
    Throws an exception on error or returns the new interface ID
    """
    session = getSessionE(session_id)
    from ccs_host import ccs_host, getHostName
    
    print interface["vid"]
    # Check interface details
    validateInterface(session_id, interface)

    # Check interface type
    if "interface_type" in interface.keys():
        try:
            it = int(interface["interface_type"])
        except:
            ccs_interface_error("Invalid interface type! Must be an integer.")
        if it <= INTERFACE_TYPE_MIN or it >= INTERFACE_TYPE_MAX:
            raise ccs_interface_error("Invalid interface type! - %s" % \
                    interface["interface_type"])
    else:
        raise ccs_interface_error("Interface type must be specified!")
    
    # Check subasset is valid if it is specified
    if "subasset_id" in interface.keys() and interface["subasset_id"]!="" \
            and int(interface["subasset_id"])!=-1:
        subasset = ccs_subasset(session_id, interface["subasset_id"])
        if not subasset.supportsFunction("interface"):
            raise ccs_interface_error("Invalid subasset type for interface!")
        if it == INTERFACE_TYPE_VAP:
            # Check specified subasset supports virtual APs
            if not subasset.supportsFunction("vap"):
                raise ccs_interface_error("Invalid subasset type for VAP " \
                        "interface")
            # XXX: Check we're not over the maximum number of vaps...
        elif not subasset.availableForInterface(interface["host_id"]):
            raise ccs_interface_error("Subasset already in use!")
    else:
        try:
            del interface["subasset_id"]
        except KeyError: pass

    # If interface is active check subasset_id is specified
    if "interface_active" in interface.keys() and \
            interface["interface_active"]=="t":
        if it == INTERFACE_TYPE_PHYSICAL or it == INTERFACE_TYPE_VAP:
            if "subasset_id" not in interface.keys():
                raise ccs_interface_error("Cannot create active " \
                        "interface without specifying a subasset!")
        elif it == INTERFACE_TYPE_VLAN or it == INTERFACE_TYPE_ALIAS:
            if "raw_interface" not in interface.keys():
                raise ccs_interface_error("Cannot create active " \
                        "interface without specifying a raw interface!")
    
    # Check VLAN properties
    if it == INTERFACE_TYPE_VLAN:
        # Check the vid is valid if specified
        if "vid" in interface.keys() and \
                interface["vid"] != "":
            print interface["vid"]
            try:
                print interface["vid"]
                vid = int(interface["vid"])
            except:
                raise ccs_interface_error("VLAN ID must be an integer")
        # VLAN interfaces have a name derived from their parent interface
        parent_iface = ccs_interface(session_id, interface["raw_interface"])
        interface["name"] = "%s.%s" % \
                (parent_iface["name"], interface["vid"])

    # Check alias properties
    if it == INTERFACE_TYPE_ALIAS:
        # Check the netmask is valid if specified
        if "alias_netmask" in interface.keys() and \
                interface["alias_netmask"] != "":
            if interface["alias_netmask"].startswith("/"):
                interface["alias_netmask"] = interface["alias_netmask"][1:]
            try:
                interface["alias_netmask"] = int(interface["alias_netmask"])
            except:
                raise ccs_interface_error("Alias netmask must be an integer")
        # Alias interfaces have a name derived from their parent interface
        parent_iface = ccs_interface(session_id, interface["raw_interface"])
        interface["name"] = "%s-alias-%s" % \
                (parent_iface["name"], interface["link_id"])

    # XXX: Check raw interface is valid if specified
           
    # Ensure boolean values are specified correctly
    for f in ["use_gateway", "interface_active", "master_interface", \
            "monitor_interface"]:
        if f not in interface.keys():
            interface[f] = "f"
        else:
            if interface[f]!="t" and interface[f]!="f":
                raise ccs_interface_error("Invalid value for " \
                        "%s parameter" % f)
    
    link = ccs_link(session_id, interface["link_id"])

    # Check IP Parameters if applicable
    if interface["monitor_interface"]=="f" and \
            (interface["bridge_interface"]=="" or \
            int(interface["bridge_interface"])==-1):
        # Check this host doesn't already have an interface on this link
        if link.connectsHost(interface["host_id"]):
            raise ccs_interface_error("Host already has an interface on the " \
                    "specified link!")
    
        # Check IP specified is correct for the link, or allocate an IP
        if "ip_address" not in interface.keys():
            interface["ip_address"] = ""
        if interface["ip_address"] == "":
            interface["ip_address"] = \
                    link.allocateIP(interface["host_id"], \
                    interface["master_interface"])
        elif not link.isValidIP(interface["ip_address"]):
            raise ccs_interface_error("Invalid IP address for link!")
    elif interface["monitor_interface"]=="f":
            # XXX: Check bridge parameters are valid
            pass
                
    # Create changeset to wrap all of this
    commit = 0
    if session.changeset == 0:
        session.begin("Created interface (%s) on host %s" % \
                (interface["name"], \
                getHostName(session_id, interface["host_id"])))
        commit = 1

    # Make sure the subasset is attached to the host
    try:
        if "subasset_id" in interface.keys():
            subasset = ccs_subasset(session_id, interface["subasset_id"])
            host = ccs_host(session_id, interface["host_id"])
            if subasset["asset_id"] != host["asset_id"]:
                subasset.attachTo(host["asset_id"])
    except:
        log_warn("Could not attach subasset (%s) to host (%s)! Interface " \
                "creation may fail!" % \
                (interface["subasset_id"], interface["host_id"]), \
                sys.exc_info())
    
    # Build list of properties for the interface type
    props = [ "interface_id", "interface_type", "host_id", "link_id", \
            "name", "use_gateway", "interface_active", "master_interface", \
            "master_mode", "master_channel", "module_id", "monitor_interface"]
    nProps = []
    if it == INTERFACE_TYPE_PHYSICAL or it == INTERFACE_TYPE_VAP :
        props.extend(["subasset_id"])
        nProps.extend(["raw_interface"])
        nProps.extend(["raw_interface", "alias_netmask"])
    elif it == INTERFACE_TYPE_VLAN:
        props.extend(["raw_interface", "vid"])
        nProps.extend(["subasset_id", "alias_netmask"])            
    elif it == INTERFACE_TYPE_ALIAS:
        props.extend(["raw_interface"])
        nProps.extend(["subasset_id"])
        if "alias_netmask" in interface.keys() and \
                interface["alias_netmask"] != "":
            props.extend(["alias_netmask"])

    if interface["monitor_interface"]=="t":
        nProps.extend(["ip_address", "bridge_interface"])
    elif interface["bridge_interface"] != "" and \
            int(interface["bridge_interface"])!=-1:
        props.extend(["bridge_interface"])
        nProps.extend(["ip_address"])
    elif interface["ip_address"] == "":
        nProps.extend(["ip_address"])
    else:
        props.extend(["ip_address"])
        nProps.extend(["bridge_interface"])
        
    # Create the interface in the database
    (sql, values) = buildInsertFromDict("interface", props, interface, True, \
            nProps)
    session.execute(sql, values)
    
    # Get the new interface id
    sql = "SELECT currval('interface_interface_id_seq') as interface_id"
    res = session.query(sql, ())
    if len(res) != 1:
        raise ccs_interface_error("Could not retrieve new interface ID!")
    interface_id = res[0]["interface_id"]
    
    # If we started a changeset, then finish it off
    if commit == 1:
        session.commit()
    
    # Fire the trigger
    triggerHostEvent(session_id, "interfaceAdded", interface["host_id"], \
            interface_id=interface_id)
    
    return interface_id