-
Notifications
You must be signed in to change notification settings - Fork 4
Retries and configure private #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,6 +27,7 @@ develop-eggs | |
| .venv | ||
| .coverage | ||
| cover | ||
| .stestr | ||
|
|
||
| # Others | ||
| .*.swp | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,11 @@ | |
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
| # License for the specific language governing permissions and limitations | ||
| # under the License. | ||
| import time | ||
|
|
||
| import tenacity | ||
|
|
||
| from netmiko.py23_compat import string_types | ||
|
|
||
| from networking_generic_switch.devices import netmiko_devices | ||
|
|
||
|
|
@@ -49,6 +54,44 @@ class Juniper(netmiko_devices.NetmikoSwitch): | |
| 'vlan members {segmentation_id}', | ||
| ) | ||
|
|
||
| @tenacity.retry(reraise=True, stop=tenacity.stop_after_attempt(3), | ||
| wait=tenacity.wait_fixed(14)) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In what conditions will this actually perform a retry? I'm not sure there is much error checking at this level, which is in itself an issue. For instance, if a bogus command were to be entered, I'm not sure that netmiko would detect the failure. It should detect failure to commit changes. |
||
| def send_config_set(self, net_connect, config_commands=None, | ||
| exit_config_mode=True, delay_factor=1, max_loops=150, | ||
| strip_prompt=False, strip_command=False, | ||
| config_mode_cmd='configure private'): | ||
| """Temporarily overriding the send_config_set method from netmiko. | ||
|
|
||
| Temporarily overriding the send_config_set method from netmiko, until | ||
| upstream patch is accepted: | ||
|
|
||
| https://github.com/ktbyers/netmiko/pull/593 | ||
|
|
||
| """ | ||
|
|
||
| delay_factor = net_connect.select_delay_factor(delay_factor) | ||
| if config_commands is None: | ||
| return '' | ||
| elif isinstance(config_commands, string_types): | ||
| config_commands = (config_commands,) | ||
|
|
||
| if not hasattr(config_commands, '__iter__'): | ||
| raise ValueError("Invalid argument passed into send_config_set") | ||
|
|
||
| # Send config commands | ||
| output = net_connect.config_mode(config_mode_cmd) | ||
| for cmd in config_commands: | ||
| net_connect.write_channel(net_connect.normalize_cmd(cmd)) | ||
| time.sleep(delay_factor * .5) | ||
|
|
||
| # Gather output | ||
| output += net_connect._read_channel_timing( | ||
| delay_factor=delay_factor, max_loops=max_loops) | ||
| if exit_config_mode: | ||
| output += net_connect.exit_config_mode() | ||
| output = net_connect._sanitize_output(output) | ||
| return output | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would this work: Once set to private config mode, netmiko should not change it to a different config mode.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, but it's a noop if the switch is already in config mode: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, the monkey patching I'm suggesting would take place entirely in netmiko_devices.juniper.Juniper and amounts to overriding the superclass _get_connection(). Darren has my example code now to take a look at. |
||
|
|
||
| def save_configuration(self, net_connect): | ||
| """Save the device's configuration. | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
14 seconds seems like quite a long delay. Would it be better to allow more retries and a shorter interval?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Darren and I talked about this. I think he used this time based on my statement as to the average commit duration. I agree with your approach of more retries at a shorter interval.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, I think your retry could just be wrapped around the net_connect.commt() call in Juniper#save_configuration(), when the former raises a ValueError. You might want to check the error message, though, to only retry when it matches the expected error ('error: configuration database locked' or whatever it is).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds like a reasonable approach. If only they'd used a more specific exception we'd be more sure of what had gone wrong.