Ejemplo n.º 1
0
def generatePlans(update):
    """
        This function looks at a diff of the current Chute (in @chuteStor) and the @newChute,
        then adds Plan() calls to make the Chute match the @newChute.

        Returns:
            True: abort the plan generation process
    """
    out.verbose("%r\n" % (update))
    
    # Generate virt start script, stored in cache (key: 'virtPreamble')
    update.plans.addPlans(plangraph.RUNTIME_GET_VIRT_PREAMBLE, (config.dockerconfig.getVirtPreamble, ))
    
    # If the user specifies DHCP then we need to generate the config and store it to disk
    update.plans.addPlans(plangraph.RUNTIME_GET_VIRT_DHCP, (config.dhcp.getVirtDHCPSettings, ))
    update.plans.addPlans(plangraph.RUNTIME_SET_VIRT_DHCP, (config.dhcp.setVirtDHCPSettings, ))

    # Reload configuration files
    todoPlan = (config.configservice.reloadAll, )
    abtPlan = [(config.osconfig.revertConfig, "dhcp"),
               (config.osconfig.revertConfig, "firewall"),
               (config.osconfig.revertConfig, "network"),
               (config.osconfig.revertConfig, "wireless"),
               (config.configservice.reloadAll, )]
    update.plans.addPlans(plangraph.RUNTIME_RELOAD_CONFIG, todoPlan, abtPlan)

    return None
Ejemplo n.º 2
0
    def __init__(self, filename=None, reactor=None):
        if not filename:
            filename = settings.FC_CHUTESTORAGE_SAVE_PATH
        PDStorage.__init__(self, filename, reactor, settings.FC_CHUTESTORAGE_SAVE_TIMER)

        # Has it been loaded?
        if len(ChuteStorage.chuteList) == 0:
            out.verbose("Loading chutes from disk: %s\n" % (filename))
            self.loadFromDisk()
Ejemplo n.º 3
0
def generatePlans(update):
    """
        This function looks at a diff of the current Chute (in @chuteStor) and the @newChute,
        then adds Plan() calls to make the Chute match the @newChute.

        Returns:
            True: abort the plan generation process
    """
    out.verbose("%r\n" % (update))

    # Detect system devices and set up basic configuration for them (WAN
    # interface, wireless devices).  These steps do not need to be reverted on
    # abort.
    #
    # abortNetworkConfig is added as an abort command here so that it runs when
    # config.network.getNetworkConfig or just about anything else fails.
    #
    # reloadAll is added as an abort command here so that it runs when any of
    # the set* plans fail and back out.
    update.plans.addPlans(plangraph.STRUCT_GET_SYSTEM_DEVICES,
                          (config.devices.getSystemDevices, ),
                          (config.network.abortNetworkConfig, ))
    update.plans.addPlans(plangraph.STRUCT_SET_SYSTEM_DEVICES,
                          (config.devices.setSystemDevices, ),
                          (config.configservice.reloadAll, ))

    update.plans.addPlans(plangraph.STRUCT_GET_HOST_CONFIG,
                          (config.hostconfig.getHostConfig, ))
    
    # Save current network configuration into chute cache (key: 'networkInterfaces')
    update.plans.addPlans(plangraph.STRUCT_GET_INT_NETWORK,
                          (config.network.getNetworkConfig, ))

    # Setup changes to push into OS config files (key: 'osNetworkConfig')
    update.plans.addPlans(plangraph.STRUCT_GET_OS_NETWORK, (config.network.getOSNetworkConfig, ))  
    
    # Setup changes to push into OS config files (key: 'osWirelessConfig')
    update.plans.addPlans(plangraph.STRUCT_GET_OS_WIRELESS, (config.wifi.getOSWirelessConfig, ))  
    
    # Setup changes into virt configuration file (key: 'virtNetworkConfig')
    update.plans.addPlans(plangraph.STRUCT_GET_VIRT_NETWORK, (config.network.getVirtNetworkConfig, ))
    
    # Changes for networking
    todoPlan = (config.network.setOSNetworkConfig, )
    abtPlan = (config.osconfig.revertConfig, 'network')
    update.plans.addPlans(plangraph.STRUCT_SET_OS_NETWORK, todoPlan, abtPlan)
    
    # Changes for wifi
    todoPlan = (config.wifi.setOSWirelessConfig, )
    abtPlan = (config.osconfig.revertConfig, 'wireless')
    update.plans.addPlans(plangraph.STRUCT_SET_OS_WIRELESS, todoPlan, abtPlan)

    return None
Ejemplo n.º 4
0
def executePlans(update):
    """
        Primary function that actually executes all the functions that were added to plans by all
        the exc modules. This function can heavily modify the OS/files/etc.. so the return value is
        very important.
        Returns:
            True in error : abortPlans function should be called
            False otherwise : everything is OK
    """
    out.header('Executing plans %r\n' % (update))
    # Finding the functions to call is actually done by a 'iterator' like function in the plangraph module
    while(True):
        # This function either returns None or a tuple just like generate added to it
        p = update.plans.getNextTodo()

        # No more to do?
        if(not p):
            break

        # Explode tuple otherwise
        func, args = p

        # We are in a try-except block so if func isn't callable that will catch it
        try:
            out.verbose('Calling %s\n' % (func))
            #
            # Call the function from the execution plan
            #
            # args may be empty, but we don't want to pass in a tuple if we don't need to
            # so this below explodes the args so if @args is (), then what is passed is @update
            skipme = func(*((update, ) + args))

        except Exception as e:
            out.exception(e, True) #, plans=str(update.plans)) # Removed because breaks new out.exception call
            update.responses.append({'exception': str(e), 'traceback': traceback.format_exc()})
            update.failure = str(e)
            return True

        # The functions we call here can return other functions, if they do these are functions that should
        # be skipped later on (for instance a set* function discovering it didn't change anything, later on
        # we shouldn't call the corresponding reload function)
        if(skipme):
            # These functions can return individual functions to skip, or a list of multiple functions
            if (not isinstance(skipme, list)):
                skipme = [skipme]

            for skip in skipme:
                out.warn('Identified a skipped function: %r\n' % (skip))
                update.plans.registerSkip(skip)

    # Now we are done
    return False
Ejemplo n.º 5
0
def generatePlans(update):
    """
        This function looks at a diff of the current Chute (in @chuteStor) and the @newChute,
        then adds Plan() calls to make the Chute match the @newChute.

        Returns:
            True: abort the plan generation process
    """
    out.verbose("%r\n" % (update))

    # If this chute is new (no old version)
    if update.old is None:
        out.verbose("new chute\n")

        # If it's a stop, start, delete, or restart command go ahead and fail right now since we don't have a record of it
        if update.updateType in ["stop", "start", "delete", "restart"]:
            update.failure = "No chute found with id: " + update.name
            return True
        # If we are now running then everything has to be setup for the first time
        if update.new.state == chute.STATE_RUNNING:
            update.plans.addPlans(plangraph.STATE_CALL_START, (virt.startChute,))

        # Check if the state is invalid, we should return bad things in this case (don't do anything)
        elif update.new.state == chute.STATE_INVALID:
            if settings.DEBUG_MODE:
                update.responses.append("Chute state is invalid")
            return True

    # Not a new chute
    else:
        if update.updateType == "start":
            if update.old.state == chute.STATE_RUNNING:
                update.failure = update.name + " already running."
                return True
            update.plans.addPlans(plangraph.STATE_CALL_START, (virt.restartChute,))
        elif update.updateType == "restart":
            update.plans.addPlans(plangraph.STATE_CALL_START, (virt.restartChute,))
        elif update.updateType == "create":
            update.failure = update.name + " already exists on this device."
            return True
        elif update.new.state == chute.STATE_STOPPED:
            if update.updateType == "delete":
                update.plans.addPlans(plangraph.STATE_CALL_STOP, (virt.removeChute,))
            if update.updateType == "stop":
                if update.old.state == chute.STATE_STOPPED:
                    update.failure = update.name + " already stopped."
                    return True
                update.plans.addPlans(plangraph.STATE_CALL_STOP, (virt.stopChute,))

    return None
Ejemplo n.º 6
0
    def delConfig(self, config, options):
        """Finds a match to the config input and removes it from the internal config data structure."""
        config = stringify(config)
        options = stringify(options)

        # Search through the config array for matches
        for i, e in enumerate(self.config):
            c, o = e
            if(c == config and o == options):
                break
        else:
            # Getting here means we didn't break so no match
            out.verbose('No match to delete, config: %r\n' % (config))
            return
        
        del(self.config[i])
Ejemplo n.º 7
0
def generatePlans(update):
    """
        This function looks at a diff of the current Chute (in @chuteStor) and the @newChute,
        then adds Plan() calls to make the Chute match the @newChute.

        Returns:
            True: abort the plan generation process
    """
    out.verbose("%r\n" % (update))

    #print any warnings from previous update if they exist
    if hasattr(update, 'pkg') and update.old != None and update.old.warning != None:
        update.pkg.request.write(update.old.warning + '\n')

    # TODO: Create a directory for the chute for us to hold onto things (dockerfile, OS config stuff)

    return None
Ejemplo n.º 8
0
        def wrapper(theSelf, request, *args, **kwargs):
            tictoc = 0  # theSelf.perf.tic()
            ip = '0.0.0.0'  # TODO getIP(request)
            out.verbose('HTTP request from IP %s\n' % (ip))
            request.setHeader('Access-Control-Allow-Origin', settings.PDFCD_HEADER_VALUE)

            apiPackage = APIPackage(request)
            # Extract required arguments
            if(requiredArgs or optionalArgs):
                body = str2json(request.content.read())
            if(requiredArgs):
                required = explode(body, *requiredArgs)
                for idx, arg in enumerate(requiredArgs):
                    # Check if required arg exist
                    if(required[idx] is None):
                        return theSelf.rest.failprocess(ip, request, (ip, theSelf.rest.clientFailures), "Malformed Body: %s", (tictoc, None), pdapi.ERR_BADPARAM)
                    # If exist put it into the apiPackage
                    apiPackage.inputArgs[arg] = required[idx]

            # Extract optional arguments
            if(optionalArgs):
                optional = explode(body, *optionalArgs)
                for idx, arg in enumerate(optionalArgs):
                    if(optional[idx]):
                        apiPackage.inputArgs[arg] = optional[idx]

            #######################################################################################
            # Make the real function call
            #######################################################################################
            func(theSelf, apiPackage, *args, **kwargs)

            # NOT_DONE_YET
            if(apiPackage.result is None):
                return NOT_DONE_YET
            # SUCCESS
            elif(apiPackage.result is True):
                theSelf.rest.postprocess(request, failureKey, failureDict, (tictoc, ip, devid))
                return apiPackage.returnVal
            # FAILURE
            else:
                errMsg = apiPackage.errMsg
                errType = apiPackage.errType
                if(apiPackage.countFailure):
                    return theSelf.rest.failprocess(ip, request, (failureKey, failureDict), errMsg, (tictoc, devid), errType)
                else:
                    return theSelf.rest.failprocess(ip, request, None, errMsg, (tictoc, devid), errType)
Ejemplo n.º 9
0
    def preprocess(self, request, checkThresh, tictoc):
        """
            Check if failure attempts for the user name has met the threshold.
            Arguments:
                request      : 
                checkThresh  : If None, no checking. Tuple of arguments for checking thresholds
                    ip: IP of client in string format
                    token: sessionToken if found, or None
                    username: username if signin, or None
                    failureDict: the dict for failure history
                ticktoc: If none, do not track the usage. The start time of the API call
            Return:
                str: if threshold is met
                None: if ok
        """

        if(checkThresh):
            ip, token, key, failureDict = checkThresh

            # Check if IP is in whitelist
            ipaddr = apiutils.unpackIPAddr(ip)
            for ipnet in self.WHITELIST_IP:
                net = apiutils.unpackIPAddrWithSlash(ipnet)
                if(apiutils.addressInNetwork(ipaddr, net)):
                    out.verbose('Request from white list: %s\n' % (ip))
                    return None

            if(key in failureDict):
                if(failureDict[key].attempts >= settings.DBAPI_FAILURE_THRESH):
                    out.err('Threshold met: %s %s!\n' % (ip, key))
                    if(tictoc is None):
                        usage = None
                    else:
                        usage = (tictoc, None)
                    self.failprocess(ip, request, (ip, failureDict), None, usage, pdapi.getResponse(pdapi.ERR_THRESHOLD))
                    duration = 0  # self.perf.toc(tictoc)
                    # Log the info of this call
                    # TODO self.usageTracker.addTrackInfo(ip, 'Null', request.path, self.usageTracker.FAIL_THRESH, duration, request.content.getvalue())

                    return "Threshold Met!"
        # Otherwise everything is ok
        return None
Ejemplo n.º 10
0
    def execute(self):
        try:
            proc = subprocess.Popen(self.command, stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE)
            self.pid = proc.pid
            for line in proc.stdout:
                out.verbose("{}: {}".format(self.command[0], line))
            for line in proc.stderr:
                out.verbose("{}: {}".format(self.command[0], line))
            self.result = proc.wait()
            out.info('Command "{}" returned {}\n'.format(
                     " ".join(self.command), self.result))
        except Exception as e:
            out.info('Command "{}" raised exception {}\n'.format(
                     " ".join(self.command), e))
            self.result = e

        if self.parent is not None:
            self.parent.executed.append(self)

        return (self.result == 0)
Ejemplo n.º 11
0
def oscall(cmd, get=False):
    """
    This function performs a OS subprocess call.
    All output is thrown away unless an error has occured or if @get is True
    Arguments:
        @cmd: the string command to run
        [get] : True means return (stdout, stderr)
    Returns:
        None if not @get and no error
        (stdout, retcode, stderr) if @get or yes error
    """
    # Since we are already in a deferred chain, use subprocess to block and make the call to mount right HERE AND NOW
    proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    output, errors = proc.communicate()
    if(proc.returncode or get):
        return (output, proc.returncode, errors)
    else:
        if(output and output != ""):
            out.verbose('"%s" stdout: "%s"\n' % (cmd, output.rstrip()))
        if(errors and errors != ""):
            out.verbose('"%s" stderr: "%s"\n' % (cmd, errors.rstrip()))
        return None