Beispiel #1
0
    def removeInterfaceSubassetLinks(self):
        """Removes the subasset associated with each interface on the host

        This function is called when the host's asset is removed, for each
        subasset that was part of the host's asset the associated interface is
        disabled and set to have no associated hardware. 

        Assets that are attached to the hosts's asset and are configured as an 
        interface are relocated to the site the host is present at.

        This needs to be called before the internal properties are updated so 
        that self._properties["asset_id"] contains the ID of the asset that is
        being removed.
        """
        session = getSessionE(self._session_id)

        # Disable the interfaces that used subassets of the host asset
        session.execute("UPDATE interface SET subasset_id=NULL, " \
                "interface_active='f' WHERE host_id=%s AND subasset_id IN " \
                "(SELECT subasset_id FROM interface_subassets WHERE " \
                "asset_id=%s)", (self.host_id, self._properties["asset_id"]))

        # Move attached assets configured as an interface to the hosts site
        res = session.query("SELECT a.asset_id FROM interface i, subasset s, " \
                "asset a WHERE i.subasset_id=s.subasset_id AND " \
                "s.asset_id=a.asset_id AND i.host_id=%s AND " \
                "i.subasset_id NOT IN (SELECT subasset_id FROM " \
                "interface_subassets WHERE asset_id=%s)", 
                (self.host_id, self._properties["asset_id"]))
        for iface in res:
            asset = ccs_asset(self._session_id, iface["asset_id"])
            if self.hasSite():
                asset.moveToSite(self._properties["site_id"])
            else:
                asset.moveToStock()
Beispiel #2
0
def setRurallinkDeviceConfig(session_id, asset_id, type):
    """Updates the device asset record to reflect the configuration type"""
    session = getSessionE(session_id)

    if asset_id == -1:
        # Called by a device itself, use the CN of the certificate to
        # lookup the mac address and find an asset ID
        mac = ":".join([session.username[(i * 2) - 2 : i * 2] for i in range(1, 7)])
        if not isValidMAC(mac):
            raise ccs_rurallink_error("Asset not specified!")
        asset = getAssetByMac(session_id, mac)
        asset_id = asset["asset_id"]

    asset = ccs_asset(session_id, asset_id)

    if type == "CPE":
        asset.updateAssetDetail("description", "RuralLink Farm Terminal")
    elif type == "Repeater":
        asset.updateAssetDetail("description", "RuralLink Farm Repeater")
    elif type == "Master":
        asset.updateAssetDetail("description", "Rurallink Farm AP (Master Node)")
    else:
        raise ccs_rurallink_error("Unknown configuration type!")

    return True
Beispiel #3
0
def registerRurallinkWirelessCard(session_id, host_asset_id, mac):
    """Called by pxe-scripts to register a new wireless card
    
    The card is also attached to the device that is used to PXE boot it
    """

    # Validate MAC address
    if not isValidMAC(mac):
        raise ccs_asset_error("Invalid MAC address!")

    try:
        asset = getAssetByMac(session_id, mac)
    except ccs_asset_error:
        # Asset does not exist
        asset = addRurallinkWirelessAsset(session_id, mac)

    # Check current location
    location = getAssetLocation(session_id, asset["asset_id"])
    if location["attached_to"] == host_asset_id:
        # Up to date
        return asset

    # Get an asset object and attach it to the host asset
    assetobj = ccs_asset(session_id, asset["asset_id"])
    assetobj.attachTo(host_asset_id)

    # Return the asset
    return asset
Beispiel #4
0
def getDevicePassword(session_id, asset_id):
    """Returns the device's password

    This password is generated by taking the Rural Link root password, 
    concatenating it with the devices MAC address and returning the last 8
    characters of an md5sum of the two
    """

    # Get the master rurallink password
    s = rurallink_service(session_id, rurallink_service.service_id)
    d = s.getDetails()
    rl_pass = d["properties"][ROOTPASS_PROPERTY]["network_value"]

    # Get the MAC address of the specified device
    asset = ccs_asset(session_id, asset_id)
    mac = asset.getMAC()

    # Calculate and return the password
    sum = md5("%s%s" % (rl_pass, mac)).hexdigest()
    return sum[-8:]
Beispiel #5
0
def addHost(session_id, host):
    """Adds a new host to the database"""
    session = getSessionE(session_id)
    
    # Check host details
    validateHost(session_id, host, True)

    # Get loopback IP if not specified
    if "ip_address" not in host.keys() or host["ip_address"] == "":
        link_class_id = None
        if "link_class_id" in host.keys():
            link_class_id = host["link_class_id"]
        host["ip_address"] = allocateLoopbackIP(session_id, link_class_id)
    
    # Build query
    props = ["host_id", "host_name", "distribution_id", "kernel_id", \
            "ip_address", "asset_id", "site_id", "host_active", "is_gateway"]
    (sql, values) = buildInsertFromDict("host", props, host)
    
    # Run query
    session.execute(sql, values)

    # Get new host id
    res = session.query("SELECT currval('host_host_id_seq') " \
            "AS host_id", ())
    if len(res) != 1 or res[0]["host_id"]<1:
        return xmlrpclib.Fault(CCSD_BADPARAM, "Could not retrieve host ID")
    host_id = res[0]["host_id"]
    
    # Update asset location if required
    if "site_id" in host.keys() and "asset_id" in host.keys() and \
            int(host["site_id"])!=-1 and int(host["asset_id"])!=-1:
        asset = ccs_asset(session_id, host["asset_id"])
        asset.moveToSite(host["site_id"])

    # Fire trigger
    triggerHostEvent(session_id, "hostAdded", host_id)

    return host_id
Beispiel #6
0
    def setAssetLocation(self, newAsset=-1, newSite=-1):
        """Moves the host asset to a new location

        If newAsset or newSite are present and are not -1 they override 
        the values stored in our current properties.
        """

        # Process overrides
        if newAsset != -1:
            asset_id = newAsset
        else:
            asset_id = self["asset_id"]
        if newSite != -1:
            site_id = newSite
        else:
            site_id = self["site_id"]
            
        # Check asset and site are specified
        if site_id == -1 or asset_id == -1:
            return
        
        # Move to site
        asset = ccs_asset(self._session_id, asset_id)
        asset.moveToSite(site_id)
Beispiel #7
0
def validateHost(session_id, details, required=False):
    """Validates the details are valid.
    
    This routine does not check for the existance of required data, it 
    only verifies that the fields in the supplied dictionary are valid.
    """
    session = getSessionE(session_id)
    
    if "host_name" in details.keys():
        if len(details["host_name"])<=0:
            raise ccs_host_error("Hostname must be greater than 0 " \
                    "characters long!")
        if len(details["host_name"]) > 64:
            raise ccs_host_error("Hostname must be less than 64 " \
                    "characters long!")
        if details["host_name"].find(" ") != -1:
            raise ccs_host_error("Hostname must not contain spaces")
    elif required:
        raise ccs_host_error("Hostname is a required field")
        
    if "distribution_id" in details.keys():
        validateDistributionId(session_id, details["distribution_id"])
    elif required:
        raise ccs_host_error("Distribution is a required field")
    
    if "kernel_id" in details.keys():
        validateKernelId(session_id, details["kernel_id"])
    elif required:
        raise ccs_host_error("Kernel is a required field")
        
    if "host_active" in details.keys():
        if details["host_active"] != "t" and details["host_active"] != "f":
            raise ccs_host_error("Invalid host status value. Must be 't' " \
                    "or 'f'")
    elif required:
        raise ccs_host_error("Host status is a required field")
        
    if "is_gateway" in details.keys():
        if details["is_gateway"] != "t" and details["is_gateway"] != "f":
            raise ccs_host_error("Invalid is gateway value. Must be 't' " \
                    "or 'f'")
    elif required:
        raise ccs_host_error("Gateway is a required field")
            
    # XXX: Check ip_address field
    
    # Site
    if "site_id" in details.keys() and int(details["site_id"])!=-1:
        validateSiteId(session_id, details["site_id"])
        
    # Asset
    if "asset_id" in details.keys() and int(details["asset_id"])!=-1:
        asset = ccs_asset(session_id, details["asset_id"])

        # Check asset is of the correct type
        if not asset.supportsFunction("host"):
            raise ccs_host_error("Specified asset is not of the " \
                    "appropriate type to use as a host!")
                    
        # Check asset isn't assigned elsewhere
        if "site_id" in details.keys():
            site_id = details["site_id"]
        else:
            site_id = -1
        if not asset.availableForHost(site_id):
            raise ccs_host_error("Specified asset already in use or " \
                    "not available!")
    
    return
Beispiel #8
0
 def moveAssetToStock(self):
     """Moves the host asset to stock, leaving it attached to the host"""
     asset = ccs_asset(self._sesion_id, self["asset_id"])
     asset.moveToStock()
Beispiel #9
0
 def removeAssetToStock(self):
     """Removes the host asset and shifts it to stock"""
     asset = ccs_asset(self._session_id, self["asset_id"])
     asset.moveToStock()
     self._properties["asset_id"] = -1
Beispiel #10
0
    def updateInterfaceSubassetLinks(self, new_asset_id):
        """Updates the subasset associated with each interface on the host

        This function is called when a hosts asset is changed. For each
        subasset that was part of the old host asset, the new asset is search
        for a subasset that matches the type and name, if one is found the 
        interface is updated to use it. Any remaining subassets on the original
        host asset after this step are matched with any free subassets of the
        appropriate type on the new asset. Any remaining subassets on the 
        original host after both these steps are disabled.

        Assets that are attached to hosts asset and are configured as an 
        interface are reattached to the new host asset.

        This needs to be called before the internal properties are updated so 
        that self._properties["asset_id"] contains the ID of the asset that is
        being removed.
        """
        session = getSessionE(self._session_id)
        used = []
        remaining = False

        # Exit now if the host did not have an asset assigned previously
        if self._properties["asset_id"] == "":
            return

        # Get a list of configured interface subassets on the old host and
        # their matching pair (based on name) on the new host
        res = session.query("SELECT a.name, a.asset_id AS old_asset_id, " \
                "a.subasset_id AS old_subasset_id, b.asset_id AS " \
                "new_asset_id, b.subasset_id AS new_subasset_id FROM " \
                "interface_subassets a LEFT JOIN interface_subassets b ON " \
                "a.name=b.name AND b.asset_id=%s WHERE a.asset_id=%s", 
                (new_asset_id, self._properties["asset_id"]))
        for match in res:
            if match["new_subasset_id"] == "":
                remaining = True
                continue
            session.execute("UPDATE interface SET subasset_id=%s WHERE " \
                    "host_id=%s AND subasset_id=%s", 
                    (match["new_subasset_id"], self.host_id, \
                            match["old_subasset_id"]))
            used.append(match["new_subasset_id"])

        # Now deal with the remainders, don't both matching names
        if remaining:
            # Fetch a list of interface subassets on the new asset
            idx = 0
            res2 = session.query("SELECT * FROM interface_subassets WHERE " \
                    "asset_id=%s", new_asset_id)
            # Loop through each remaining subasset from the old asset
            for match in res:
                if match["new_subasset_id"] != "":
                    continue
                fixed = False
                while idx < len(res2):
                    # Check this subasset wasn't used above
                    if res2[idx]["subasset_id"] in used:
                        idx += 1
                        continue
                    # Use it
                    session.execute("UPDATE interface SET subasset_id=%s " \
                            "WHERE host_id=%s AND subasset_id=%s", 
                            (res2[idx]["subasset_id"], self.host_id, \
                                    match["old_subasset_id"]))
                    used.append(res2[idx]["new_subasset_id"])
                    idx += 1
                    fixed = True
                    break
                # Disable if not fixed
                if not fixed:
                    session.execute("UPDATE interface SET subasset_id=NULL, " \
                            "interface_active='f' WHERE host_id=%s AND " \
                            "subasset_id=%s", (self.host_id, \
                            match["old_subasset_id"]))
                            
        # Move attached assets configured as an interface to the hosts site
        res = session.query("SELECT a.asset_id FROM interface i, subasset s, " \
                "asset a WHERE i.subasset_id=s.subasset_id AND " \
                "s.asset_id=a.asset_id AND i.host_id=%s AND " \
                "i.subasset_id NOT IN (SELECT subasset_id FROM " \
                "interface_subassets WHERE asset_id=%s OR asset_id=%s)", 
                (self.host_id, self._properties["asset_id"], new_asset_id))
        for iface in res:
            asset = ccs_asset(self._session_id, iface["asset_id"])
            asset.attachTo(new_asset_id)