def _determine_current_priv(self, current_prompt: str) -> List[str]: """ Determine current privilege level from prompt string Args: current_prompt: string of current prompt Returns: matching_priv_levels: list of string names of matching privilege levels Raises: UnknownPrivLevel: if privilege level cannot be determined """ matching_priv_levels = [] for priv_level in self.privilege_levels.values(): search_result = re.search(pattern=priv_level.pattern, string=current_prompt, flags=re.M | re.I) if not search_result: continue matching_priv_levels.append(priv_level.name) self.logger.debug( f"Current privilege level could be `{priv_level.name}`") if not matching_priv_levels: raise UnknownPrivLevel( f"Could not determine privilege level from provided prompt: `{current_prompt}`" ) self.logger.debug( f"Determined current privilege level is one of `{matching_priv_levels}`" ) return matching_priv_levels
def _escalate(self) -> None: """ Escalate to the next privilege level up Args: N/A Returns: N/A # noqa: DAR202 Raises: UnknownPrivLevel: if priv level cant be attained TypeError: if invalid next prompt value """ current_priv = self._determine_current_priv(self.channel.get_prompt()) if not current_priv.escalate: return next_priv = self.privs.get(current_priv.escalate_priv, None) if next_priv is None: raise UnknownPrivLevel( f"Could not get next priv level, current priv is {current_priv.name}" ) next_prompt = next_priv.pattern if current_priv.escalate_auth: if not self.auth_secondary: err = ( "Privilege escalation generally requires an `auth_secondary` password, " "but none is set!") msg = f"***** {err} {'*' * (80 - len(err))}" fix = ( "scrapli will try to escalate privilege without entering a password but may " "fail.\nSet an `auth_secondary` password if your device requires a password to " "increase privilege, otherwise ignore this message.") warning = "\n" + msg + "\n" + fix + "\n" + msg warnings.warn(warning) else: escalate_cmd: str = current_priv.escalate escalate_prompt: str = current_priv.escalate_prompt escalate_auth = self.auth_secondary if not isinstance(next_prompt, str): raise TypeError( f"got {type(next_prompt)} for {current_priv.name} escalate priv, " "expected str") self.channel.send_inputs_interact( [ escalate_cmd, escalate_prompt, escalate_auth, next_prompt ], hidden_response=True, ) self.channel.comms_prompt_pattern = next_priv.pattern return self.channel.comms_prompt_pattern = next_priv.pattern self.channel.send_input(current_priv.escalate)
def _get_privilege_level_name(self, requested_priv: str) -> str: """ Get privilege level name if provided privilege is valid Args: requested_priv: string name of desired privilege level Returns: str: name of the privilege level requested Raises: UnknownPrivLevel: if attempting to acquire an unknown priv """ desired_privilege_level = self.privilege_levels.get( requested_priv, None) if desired_privilege_level is None: raise UnknownPrivLevel( f"Requested privilege level `{requested_priv}` not a valid privilege level of " f"`{self.__class__.__name__}`") resolved_privilege_level = desired_privilege_level.name return resolved_privilege_level
def _deescalate(self) -> None: """ Deescalate to the next privilege level down Args: N/A Returns: N/A # noqa: DAR202 Raises: UnknownPrivLevel: if no default priv level set to deescalate to """ current_priv = self._determine_current_priv(self.channel.get_prompt()) if current_priv.deescalate: next_priv = self.privs.get(current_priv.deescalate_priv, None) if not next_priv: raise UnknownPrivLevel( "NetworkDriver has no default priv levels, set them or use a network driver" ) self.channel.comms_prompt_pattern = next_priv.pattern self.channel.send_input(current_priv.deescalate)