コード例 #1
0
async def run_query(query):
    """Execute validated query & parse the results.

    Arguments:
        query {object} -- Validated query object

    Raises:
        ExecutionError: If stderr exists

    Returns:
        {str} -- Parsed output string
    """
    log.debug(f"Query: {query}")

    parser_map = {"bird": parse_bird_output, "frr": parse_frr_output}
    parser = parser_map[params.mode]

    command_raw = operator.attrgetter(".".join(
        [params.mode, query.afi, query.query_type]))(commands)

    log.debug(f"Raw Command: {command_raw}")

    command = command_raw.format(**query.dict())

    log.debug(f"Formatted Command: {command}")

    proc = await asyncio.create_subprocess_shell(
        command,
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE)
    stdout, stderr = await proc.communicate()

    if stderr:
        err_output = stderr.decode()
        log.error(err_output)
        raise ExecutionError(err_output)

    output = ""

    if stdout:
        log.debug(f"Parser: {parser.__name__}")

        raw_output = stdout.decode()
        output += await parser(raw=raw_output,
                               query_data=query,
                               not_found=params.not_found_message)
        return output

    if not output and proc.returncode == 0:
        output = await parser(raw="",
                              query_data=query,
                              not_found=params.not_found_message)
    return output
コード例 #2
0
async def parse_frr_output(raw, query_data, not_found):
    """Parse raw CLI output from FRR (vtysh) and return parsed output.

    Arguments:
        raw {str} -- Raw output from vtysh
        query_data {object} -- Validated query object
        not_found {str} -- Lookup not found message template

    Returns:
        {str} -- Parsed output
    """
    raw_split = raw.strip()
    if not raw_split:
        notfound_message = not_found.format(
            target=query_data.target, afi=AFI_DISPLAY_MAP[query_data.afi])
        output = notfound_message
    else:
        output = raw_split

    log.debug(f"Parsed output:\n{output}")
    return output
コード例 #3
0
async def query_entrypoint(query: EncodedRequest):
    """Validate and process input request.

    Arguments:
        query {dict} -- Encoded JWT

    Returns:
        {obj} -- JSON response
    """
    try:
        log.debug(f"Raw Query JSON: {query.json()}")

        decrypted_query = await jwt_decode(query.encoded)
        decrypted_query = json.loads(decrypted_query)

        log.debug(f"Decrypted Query: {decrypted_query}")

        validated_query = Request(**decrypted_query)
        query_output = await run_query(validated_query)

        log.debug(f"Query Output:\n{query_output}")

        encoded = await jwt_encode(query_output)
        return {"encoded": encoded}

    except ValidationError as err_validation:
        raise RequestValidationError(str(err_validation))

    except HyperglassAgentError as err_agent:
        raise HTTPException(status_code=err_agent.code, detail=str(err_agent))
コード例 #4
0
ファイル: bird.py プロジェクト: Napsterbater/hyperglass-agent
async def get_bird_version():
    """Get BIRD version from command line.

    Raises:
        ExecutionError: Raised when `birdc` is not found on the system.
        ExecutionError: Raised when the output is unreadable or contains errors.

    Returns:
        {int} -- Major BIRD version.
    """
    proc = await asyncio.create_subprocess_shell(
        cmd="bird --version",
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE,
    )
    stdout, stderr = await proc.communicate()

    if stdout:
        raw_output = stdout.decode("utf-8")

    if stderr and b"BIRD version" in stderr:
        raw_output = stderr.decode("utf-8")

    elif stderr and b"command not found" in stderr:
        raise ExecutionError(
            ("BIRD mode is configured, but bird does not appear to be "
             f'installed: {stderr.decode("utf-8")}'))

    elif stderr and b"BIRD version" not in stderr:
        raise ExecutionError(stderr.decode("utf-8"))

    # Extract numbers from string as list of numbers
    version_str = re.findall(r"\d+", raw_output)

    # Filter major release number & convert to int
    version = int(version_str[0])

    log.debug(f"BIRD Major Version: {version_str[0]}")
    return version
コード例 #5
0
ファイル: bird.py プロジェクト: Napsterbater/hyperglass-agent
async def parse_bird_output(raw, query_data, not_found):
    """Parse raw BIRD output and return parsed output.

    Arguments:
        raw {str} -- Raw BIRD output
        query_data {object} -- Validated query object
        not_found {str} -- Lookup not found message template

    Returns:
        str -- Parsed output
    """
    raw_split = re.split(r"(Table)", raw.strip())
    raw_joined = "".join(raw_split[1::])

    if not raw_joined:
        notfound_message = not_found.format(
            target=query_data.target, afi=AFI_DISPLAY_MAP[query_data.afi])
        output = notfound_message
    else:
        output = raw_joined

    log.debug(f"Parsed output:\n{output}")
    return output
コード例 #6
0
    _commands = _raw_config.pop("commands", None)
    _user_config = General(**_raw_config)

    if _commands is not None:
        _user_commands = Commands.import_params(mode=_user_config.mode,
                                                **_commands)
    else:
        _user_commands = Commands.import_params(mode=_user_config.mode)

except ValidationError as validation_errors:
    _errors = validation_errors.errors()
    for error in _errors:
        raise ConfigInvalid(
            field=": ".join([str(item) for item in error["loc"]]),
            error_msg=error["msg"],
        )

LOG_LEVEL = "INFO"
if _user_config.debug:
    LOG_LEVEL = "DEBUG"
    LOG_HANDLER["level"] = LOG_LEVEL
    log.remove()
    log.configure(handlers=[LOG_HANDLER], levels=LOG_LEVELS)
    log.debug("Debugging Enabled")

params = _user_config
commands = _user_commands

log.debug(params.json())
log.debug(commands.json())