diff --git a/docs/advanced-topics.md b/docs/advanced-topics.md index 442a2318..b8c2fd64 100644 --- a/docs/advanced-topics.md +++ b/docs/advanced-topics.md @@ -160,6 +160,7 @@ base_options: dict = { "idempotent_commands": [], "negation_default_when": [], "negation_negate_with": [], + "negation_replace": [], } ``` @@ -348,6 +349,40 @@ coming soon... coming soon... +#### negation_replace + +Used to apply exceptions on 'no' commands. This option is similar to +per_line_sub but applied in the config removal pipeline. + +Mandatory parameters: +```text +search - regex to match and separate by groups +replace - replaced expression used by re.sub. Can be a fixed string or a group + sorted in search +``` + +e.g. - ipv6 prefix-list commands: +```text +ipv6 prefix-list spine-to-leaf-v6 seq 1 permit 2801:80:3ea1:1::/64 ge 65 +no ipv6 prefix-list spine-to-leaf-v6 seq 1 +``` + +```yaml +negation_replace: +- lineage: + - re_search: ipv6 prefix-list \b.* permit + search: (ipv6 prefix-list \b.* seq \b[0-9]+).(permit\b.*) + replace: 'no \1 ' +``` + +```text +original: +no ipv6 prefix-list spine-to-leaf-v6 seq 1 permit 2801:80:3ea1:1::/64 ge 65 + +result: +no ipv6 prefix-list spine-to-leaf-v6 seq 1 +``` + ## Custom hier_config Workflows Coming soon... diff --git a/hier_config/child.py b/hier_config/child.py index 7caf75d5..eb552ae3 100644 --- a/hier_config/child.py +++ b/hier_config/child.py @@ -15,6 +15,7 @@ from .base import HConfigBase from . import text_match +import re if TYPE_CHECKING: from .root import HConfig @@ -219,6 +220,13 @@ def negate(self) -> HConfigChild: if self.lineage_test(rule): return self._default() + if "negation_replace" in self.options.keys(): + for rule in self.options["negation_replace"]: + if self.lineage_test(rule): + line = re.sub(rule["search"], rule["replace"], self.text) + self.text = line + return self + return self._swap_negation() @property diff --git a/hier_config/options.py b/hier_config/options.py index 13e72018..8a82874f 100644 --- a/hier_config/options.py +++ b/hier_config/options.py @@ -12,6 +12,7 @@ "idempotent_commands": [], "negation_default_when": [], "negation_negate_with": [], + "negation_replace": [], } ios_options: dict = { "style": "ios", diff --git a/tests/fixtures/options_ios.yml b/tests/fixtures/options_ios.yml index 92b80e6a..bde83c40 100644 --- a/tests/fixtures/options_ios.yml +++ b/tests/fixtures/options_ios.yml @@ -117,3 +117,7 @@ negation_default_when: [] # - startswith: description # use: no description negation_negate_with: [] + +# Negate expressions with replace: lineage expression -> negate replace +# Use search and replace options to find and replace some line expression +negation_replace: []