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
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
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
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)
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"
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
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
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
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
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
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"
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
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
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
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
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
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)
def response_obj(): return ScrapliCfgResponse(host="localhost")