예제 #1
0
    def _post_commit_config(
        self,
        response: ScrapliCfgResponse,
        scrapli_responses: List[Union[Response, MultiResponse]],
    ) -> ScrapliCfgResponse:
        """
        Handle post "commit_config" operations for parity between sync and async

        Args:
            response: response object to update
            scrapli_responses: list of scrapli response objects from committing the config

        Returns:
            ScrapliCfgResponse: response object

        Raises:
            N/A

        """
        response.record_response(scrapli_responses=scrapli_responses)

        if response.failed:
            msg = "failed to commit config"
            self.logger.critical(msg)

        return response
예제 #2
0
    def _post_get_config(
        self,
        response: ScrapliCfgResponse,
        source: str,
        scrapli_responses: List[Union[Response, MultiResponse]],
        result: str,
    ) -> ScrapliCfgResponse:
        """
        Handle post "get_config" operations for parity between sync and async

        Args:
            response: response object to update
            source: name of the config source, generally running|startup
            scrapli_responses: list of scrapli response objects from fetching the config
            result: final string of the "get_config" result

        Returns:
            ScrapliCfgResponse: response object containing string of the target config source as the
                `result` attribute

        Raises:
            N/A

        """
        response.record_response(scrapli_responses=scrapli_responses,
                                 result=result)

        if response.failed:
            msg = f"failed to get {source} config"
            self.logger.critical(msg)

        return response
예제 #3
0
    def _post_get_version(
        self,
        response: ScrapliCfgResponse,
        scrapli_responses: List[Response],
        result: str,
    ) -> ScrapliCfgResponse:
        """
        Handle post "get_version" operations for parity between sync and async

        Args:
            response: response object to update
            scrapli_responses: list of scrapli response objects from fetching the version
            result: final version string of the device

        Returns:
            ScrapliCfgResponse: response object containing string of the version as the `result`
                attribute

        Raises:
            N/A

        """
        response.record_response(scrapli_responses=scrapli_responses,
                                 result=result)

        if response.failed:
            msg = "failed to get version from device"
            self.logger.critical(msg)

        return response
예제 #4
0
def test_validate_and_set_version_failed_to_parse(base_cfg_object):
    failed_to_parse_version_response = ScrapliCfgResponse(host="localhost")
    failed_to_parse_version_response.record_response(scrapli_responses=[],
                                                     result="")
    with pytest.raises(VersionError):
        base_cfg_object._validate_and_set_version(
            version_response=failed_to_parse_version_response)
예제 #5
0
def test_validate_and_set_version(base_cfg_object):
    assert base_cfg_object._version_string == ""
    version_response = ScrapliCfgResponse(host="localhost")
    version_response.record_response(scrapli_responses=[], result="1.2.3")
    base_cfg_object._validate_and_set_version(
        version_response=version_response)
    assert base_cfg_object._version_string == "1.2.3"
예제 #6
0
    def _post_clear_config_sessions(
        self,
        response: ScrapliCfgResponse,
        scrapli_responses: Iterable[Response],
    ) -> ScrapliCfgResponse:
        """
        Handle post "clear_config_sessions" operations for parity between sync and async

        Args:
            response: response object to update
            scrapli_responses: list of scrapli response objects from fetching the version

        Returns:
            ScrapliCfgResponse: response object containing string of the version as the `result`
                attribute

        Raises:
            N/A

        """
        response.record_response(scrapli_responses=scrapli_responses)

        if response.failed:
            msg = "failed to clear device configuration session(s)"
            self.logger.critical(msg)
            response.result = msg
        else:
            response.result = "configuration session(s) cleared"

        return response
예제 #7
0
    def _pre_get_config(self, source: str) -> ScrapliCfgResponse:
        """
        Handle pre "get_config" operations for parity between sync and async

        Args:
            source: name of the config source, generally running|startup

        Returns:
            ScrapliCfgResponse: new response object to update w/ get results

        Raises:
            InvalidConfigTarget: if the requested config source is not valid

        """
        self.logger.info(f"get_config for config source '{source}' requested")

        self._operation_ok()

        if source not in self.config_sources:
            msg = (
                f"provided config source '{source}' not valid, must be one of {self.config_sources}"
            )
            self.logger.critical(msg)
            raise InvalidConfigTarget(msg)

        response = ScrapliCfgResponse(
            host=self.conn.host, raise_for_status_exception=GetConfigError)

        return response
예제 #8
0
    def _pre_abort_config(self,
                          session_or_config_file: bool) -> ScrapliCfgResponse:
        """
        Handle pre "abort_config" operations for parity between sync and async

        Args:
            session_or_config_file: bool indicating if a session or candidate config file has been
                loaded -- in other words, is there anything to abort right now

        Returns:
            ScrapliCfgResponse: response object for abort operation

        Raises:
            AbortConfigError: if no config session or config file exists then we have no config to
                abort!

        """
        self.logger.info("abort_config requested")

        self._operation_ok()

        if session_or_config_file is False:
            msg = (
                "no configuration session or candidate configuration file exists, you must load a "
                "config in order to abort it!")
            self.logger.critical(msg)
            raise AbortConfigError(msg)

        response = ScrapliCfgResponse(
            host=self.conn.host, raise_for_status_exception=AbortConfigError)

        return response
예제 #9
0
    def _pre_get_checkpoint(
        self, conn: Union[AsyncNetworkDriver, NetworkDriver]
    ) -> Tuple[ScrapliCfgResponse, List[str]]:
        """
        Handle pre "get_checkpoint" operations for parity between sync and async

        Args:
            conn: connection from the sync or async platform; passed in explicitly to maintain
                typing sanity

        Returns:
            list: list of commands needed to generate checkpoint and show it

        Raises:
            N/A

        """
        self.logger.info("get_checkpoint requested")

        tmp_timestamp = round(datetime.now().timestamp())
        checkpoint_commands = [
            "terminal dont-ask",
            f"checkpoint file {self.filesystem}scrapli_cfg_tmp_{tmp_timestamp}",
            f"show file {self.filesystem}scrapli_cfg_tmp_{tmp_timestamp}",
            f"delete {self.filesystem}scrapli_cfg_tmp_{tmp_timestamp}",
        ]

        response = ScrapliCfgResponse(
            host=conn.host, raise_for_status_exception=GetConfigError)

        return response, checkpoint_commands
예제 #10
0
def test_post_commit_config(base_cfg_object):
    # send a failed response so we also cover the logger message indicating that there was a fail
    commit_config_response = ScrapliCfgResponse(host="localhost")
    scrapli_response = Response(host="localhost",
                                channel_input="commit a config")
    post_commit_config_response = base_cfg_object._post_commit_config(
        response=commit_config_response, scrapli_responses=[scrapli_response])
    assert post_commit_config_response.failed is True
예제 #11
0
def test_post_get_version(base_cfg_object):
    # send a failed response so we also cover the logger message indicating that there was a fail
    get_version_response = ScrapliCfgResponse(host="localhost")
    scrapli_response = Response(host="localhost", channel_input="show version")
    post_get_version_response = base_cfg_object._post_get_version(
        response=get_version_response,
        scrapli_responses=[scrapli_response],
        result="blah")
    assert post_get_version_response.failed is True
    assert post_get_version_response.result == "blah"
예제 #12
0
    def _pre_get_version(self) -> ScrapliCfgResponse:
        """
        Handle pre "get_version" operations for parity between sync and async

        Args:
            N/A

        Returns:
            ScrapliCfgResponse: new response object to update w/ get results

        Raises:
            N/A

        """
        self.logger.info("get_version requested")

        response = ScrapliCfgResponse(host=self.conn.host,
                                      raise_for_status_exception=VersionError)

        return response
예제 #13
0
    def _pre_clear_config_sessions(self) -> ScrapliCfgResponse:
        """
        Handle pre "clear_config_sessions" operations for parity between sync and async

        Args:
            N/A

        Returns:
            ScrapliCfgResponse: new response object to update w/ get results

        Raises:
            N/A

        """
        self.logger.info("clear_config_sessions requested")

        response = ScrapliCfgResponse(
            host=self.conn.host,
            raise_for_status_exception=ScrapliCfgException)

        return response
예제 #14
0
    def _pre_commit_config(self, source: str,
                           session_or_config_file: bool) -> ScrapliCfgResponse:
        """
        Handle pre "commit_config" operations for parity between sync and async

        Args:
            source: name of the config source, generally running|startup
            session_or_config_file: bool indicating if a session or candidate config file has been
                loaded -- in other words, is there anything to commit right now

        Returns:
            ScrapliCfgResponse: new response object to update w/ commit results

        Raises:
            InvalidConfigTarget: if the requested config source is not valid
            CommitConfigError: if no config session/file exists to commit

        """
        self.logger.info(f"get_config for config source '{source}' requested")

        self._operation_ok()

        if source not in self.config_sources:
            msg = (
                f"provided config source '{source}' not valid, must be one of {self.config_sources}"
            )
            self.logger.critical(msg)
            raise InvalidConfigTarget(msg)

        if session_or_config_file is False:
            msg = (
                "no configuration session or candidate configuration file exists, you must load a "
                "config in order to commit it!")
            self.logger.critical(msg)
            raise CommitConfigError(msg)

        response = ScrapliCfgResponse(
            host=self.conn.host, raise_for_status_exception=CommitConfigError)

        return response
예제 #15
0
    def _pre_load_config(self, config: str) -> ScrapliCfgResponse:
        """
        Handle pre "load_config" operations for parity between sync and async

        Args:
            config: candidate config to load

        Returns:
            ScrapliCfgResponse: new response object for load operation

        Raises:
            N/A

        """
        self.logger.info("load_config requested")

        self._operation_ok()

        self.candidate_config = config

        response = ScrapliCfgResponse(
            host=self.conn.host, raise_for_status_exception=LoadConfigError)

        return response
예제 #16
0
 async def _get_config(cls, source):
     nonlocal get_config_called
     get_config_called = True
     response = ScrapliCfgResponse(host="localhost")
     response.result = "blah\nmatchthisline\nanotherblah"
     return response
예제 #17
0
def test_validate_and_set_version_failed(base_cfg_object):
    failed_version_response = ScrapliCfgResponse(host="localhost")
    with pytest.raises(VersionError):
        base_cfg_object._validate_and_set_version(
            version_response=failed_version_response)
예제 #18
0
def response_obj():
    return ScrapliCfgResponse(host="localhost")