carlmontanari / scrapli

Fast, flexible, sync/async, Python 3.7+ screen scraping client specifically for network devices
https://carlmontanari.github.io/scrapli/
MIT License
575 stars 59 forks source link

Finding a `interaction_complete_patterns` does not end interactive session #318

Open MattCatz opened 7 months ago

MattCatz commented 7 months ago

Describe the bug According to the documentation of send_interactive (specifically in sync_driver.py)

interaction_complete_patterns: list of patterns, that if seen, indicate the interactive
                "session" has ended and we should exit the interactive session.

I take this to mean that no more input will be send if one of those patterns is seen. The actual behavior is slightly different. It handles these patterns like the prompt and continues to send input after seeing one.

This is also supported if you dig down into the code. Going GenericDriver.send_interactive -> Channel.send_inputs_interact you can see that it is impossible to gracefully break out of the for interact_event in interact_events loop (i.e. all interactive events will be sent).

https://github.com/carlmontanari/scrapli/blob/ac1446873929bd9f4732f07ab4993fbeefb47236/scrapli/channel/sync_channel.py#L644-L670

carlmontanari commented 7 months ago

yeah probably should be a check on buf if it contains any of the complete patterns. up for pr? if yes, please do async too :)

carlmontanari commented 7 months ago

for whatever reason (no good one I assume) looks like this is "correct" in scrapligo, so can probably steal from that sorta too (though guess it should be fairly straight forward fix anywho)

MattCatz commented 7 months ago

On a tangent to this bug, would you also want to end the interactive session if the a failed_when_contains pattern is found? Something like this seems a bit redundant (but I could see it either way).

        interact = conn.channel.send_inputs_interact(
            [
                ("copy flash: scp:", "Source filename []?", False),
                ("test1.txt", "Address or name of remote host []?", False),
                ("172.31.254.100", "Destination username [carl]?", False),
                ("carl", "Password:", False),
                ("super_secure_password", prompt, True),
            ],
            failed_when_contains=["file not found"],
            interaction_complete_patterns=["file not found"]
        )
carlmontanari commented 7 months ago

hmm a good question for sure...

its probably not a bad idea to add, but that is certainly more work :)

in general I would kind of avoid the send_interactive stuff anyway and would prefer to use the read callback bits that are of course not really documented much (at all?!). so I guess what id vote to do is probably to just fix the initial issue and not mess about with adding the failed when stuff. for more fancy things you could do the read callback thing where you basically can do whatever you want in a less rigid way than this anyway.