Example #1
0
    async def response(self):
        """Initiate query validation and execution."""
        device = getattr(devices, self.query_location)

        log.debug(f"Received query for {self.query_data}")
        log.debug(f"Matched device config: {device}")

        supported, transport = validate_nos(device.nos)

        connect = None
        output = params.messages.general
        connect = Connect(device, self.query_data, transport)

        if supported and transport == "rest":
            output = await connect.rest()

        elif supported and transport == "scrape":
            if device.proxy:
                output = await connect.scrape_proxied()
            else:
                output = await connect.scrape_direct()
        else:
            raise ConfigError('"{nos}" is not supported.', nos=device.nos)

        if output == "" or output == "\n":
            raise ResponseEmpty(params.messages.no_output,
                                device_name=device.display_name)

        log.debug(
            f"Output for query: {self.query_data.json()}:\n{repr(output)}")

        return output
Example #2
0
    def supported_nos(cls, value):
        """Validate that nos is supported by hyperglass.

        Raises:
            UnsupportedDevice: Raised if nos is unsupported.

        Returns:
            {str} -- Valid NOS
        """
        if value in SCRAPE_HELPERS.keys():
            value = SCRAPE_HELPERS[value]

        supported, _ = validate_nos(value)

        if not supported:
            raise UnsupportedDevice('"{nos}" is not supported.', nos=value)

        return value
Example #3
0
async def execute(query: Query) -> Union[str, Sequence[Dict]]:
    """Initiate query validation and execution."""

    output = params.messages.general

    log.debug("Received query for {}", query.json())
    log.debug("Matched device config: {}", query.device)

    supported, driver_name = validate_nos(query.device.nos)

    mapped_driver = DRIVER_MAP.get(driver_name, NetmikoConnection)
    driver = mapped_driver(query.device, query)

    timeout_args = {
        "unformatted_msg": params.messages.connection_error,
        "device_name": query.device.name,
        "error": params.messages.request_timeout,
    }

    if query.device.proxy:
        timeout_args["proxy"] = query.device.proxy.name

    signal.signal(signal.SIGALRM, handle_timeout(**timeout_args))
    signal.alarm(params.request_timeout - 1)

    if query.device.proxy:
        proxy = driver.setup_proxy()
        with proxy() as tunnel:
            response = await driver.collect(
                tunnel.local_bind_host, tunnel.local_bind_port
            )
    else:
        response = await driver.collect()

    output = await driver.parsed_response(response)

    if output == "" or output == "\n":
        raise ResponseEmpty(params.messages.no_output, device_name=query.device.name)

    log.debug("Output for query: {}:\n{}", query.json(), repr(output))
    signal.alarm(0)

    return output
Example #4
0
    def validate_nos_commands(cls, values: "Device") -> "Device":
        """Validate & rewrite NOS, set default commands."""

        nos = values.get("nos", "")
        if not nos:
            # Ensure nos is defined.
            raise ValueError(
                f'Device {values["name"]} is missing a `nos` (Network Operating System).'
            )

        if nos in SCRAPE_HELPERS.keys():
            # Rewrite NOS to helper value if needed.
            nos = SCRAPE_HELPERS[nos]

        # Verify NOS is supported by hyperglass.
        supported, _ = validate_nos(nos)
        if not supported:
            raise UnsupportedDevice('"{nos}" is not supported.', nos=nos)

        values["nos"] = nos

        commands = values.get("commands")

        if commands is None:
            # If no commands are defined, set commands to the NOS.
            inferred = values["nos"]

            # If the _telnet prefix is added, remove it from the command
            # profile so the commands are the same regardless of
            # protocol.
            if "_telnet" in inferred:
                inferred = inferred.replace("_telnet", "")

            values["commands"] = inferred

        return values