async def diff_config(self, source: str = "running") -> ScrapliCfgDiffResponse: scrapli_responses = [] device_diff = "" source_config = "" diff_response = self._pre_diff_config( source=source, session_or_config_file=bool(self.candidate_config_filename)) try: diff_command = self._get_diff_command(source=source) if diff_command: diff_result = await self.conn.send_command(command=diff_command ) scrapli_responses.append(diff_result) if diff_result.failed: msg = "failed generating diff for config session" self.logger.critical(msg) raise DiffConfigError(msg) device_diff = diff_result.result else: device_diff = "" source_config_result = await self.get_config(source=source) source_config = source_config_result.result if isinstance(source_config_result.scrapli_responses, MultiResponse): # in this case this will always be a multiresponse or nothing (failure) but mypy # doesnt know that, hence the isinstance check scrapli_responses.extend( source_config_result.scrapli_responses) if source_config_result.failed: msg = "failed fetching source config for diff comparison" self.logger.critical(msg) raise DiffConfigError(msg) except DiffConfigError: pass return self._post_diff_config( diff_response=diff_response, scrapli_responses=scrapli_responses, source_config=self.clean_config(source_config), candidate_config=self.clean_config(self.candidate_config), device_diff=device_diff, )
async def diff_config(self, source: str = "running") -> ScrapliCfgDiffResponse: scrapli_responses = [] device_diff = "" source_config = "" diff_response = self._pre_diff_config( source=source, session_or_config_file=bool(self.candidate_config_filename)) try: diff_result = await self.conn.send_command( command=self._get_diff_command(source=source)) scrapli_responses.append(diff_result) if diff_result.failed: msg = "failed generating diff for config session" self.logger.critical(msg) raise DiffConfigError(msg) device_diff = diff_result.result source_config_result = await self.get_config(source=source) source_config = source_config_result.result if isinstance(source_config_result.scrapli_responses, list): scrapli_responses.extend( source_config_result.scrapli_responses) if source_config_result.failed: msg = "failed fetching source config for diff comparison" self.logger.critical(msg) raise DiffConfigError(msg) except DiffConfigError: pass return self._post_diff_config( diff_response=diff_response, scrapli_responses=scrapli_responses, source_config=self.clean_config(source_config), candidate_config=self.clean_config(self.candidate_config), device_diff=device_diff, )
def _pre_diff_config( self, source: str, session_or_config_file: bool) -> ScrapliCfgDiffResponse: """ Handle pre "diff_config" operations for parity between sync and async Args: source: config source to diff against session_or_config_file: bool of config_session_name or candidate_config_filename Returns: ScrapliCfgDiffResponse: diff object for diff operation Raises: InvalidConfigTarget: if trying to diff against an invalid config target DiffConfigError: if no config session or config file exists then we have no config to diff! """ self.logger.info("diff_config 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 diff it!") self.logger.critical(msg) raise DiffConfigError(msg) diff_response = ScrapliCfgDiffResponse(host=self.conn.host, source=source) return diff_response