-
Notifications
You must be signed in to change notification settings - Fork 29
Description
Is your feature request related to a problem? Please describe.
There are scenarios where the default diff-based remediation workflow produces technically correct but operationally unsafe command sequences. The most common example is ACL modifications on live devices: when removing a deny ip any any rule and adding a new permit rule, the standard remediation will remove the deny first, potentially allowing unwanted traffic during the configuration change window.
Currently, there's no native way within the driver framework to intercept and transform the remediation config after it's computed but before it's applied. Users must write separate post-processing scripts that manipulate the remediation output, which:
- Duplicates the tree manipulation logic outside the driver
- Breaks the cohesive driver-based design pattern
- Makes it harder to share platform-specific remediation patterns
- Cannot leverage the full HConfig API during transformation
Describe the solution you'd like
Add a remediation_transform_callbacks field to HConfigDriverRules (similar to the existing post_load_callbacks), allowing drivers to register callbacks that transform the remediation config after diff computation.
Proposed Implementation:
- Add new field to
HConfigDriverRulesindriver_base.py:
remediation_transform_callbacks: list[Callable[[HConfig], None]] = Field(
default_factory=list
)- Update
WorkflowRemediation.remediation_configproperty inworkflows.pyto apply transforms:
@property
def remediation_config(self) -> HConfig:
if self._remediation_config:
return self._remediation_config
remediation_config = self.running_config.config_to_get_to(
self.generated_config
).set_order_weight()
# Apply driver-specific remediation transforms
for callback in remediation_config.driver.rules.remediation_transform_callbacks:
callback(remediation_config)
self._remediation_config = remediation_config
return self._remediation_config- Platform drivers can then define transforms:
# In cisco_ios/driver.py
def _safe_acl_remediation(remediation: HConfig) -> None:
"""Add temporary permit-all safety net for ACL modifications."""
for acl in remediation.get_children(startswith="ip access-list extended"):
# Check if we're removing deny rules
has_deny_removals = any(
child.text.startswith("no") and "deny" in child.text
for child in acl.children
)
if has_deny_removals:
# Add safety entry at the beginning
safety_child = acl.add_child(" 1 permit ip any any")
safety_child.order_weight = -1000
# Add cleanup at the end
cleanup_child = acl.add_child(" no 1")
cleanup_child.order_weight = 1000
class HConfigDriverCiscoIOS(HConfigDriverBase):
@staticmethod
def _instantiate_rules() -> HConfigDriverRules:
return HConfigDriverRules(
# ... existing rules ...
post_load_callbacks=[
_rm_ipv6_acl_sequence_numbers,
_remove_ipv4_acl_remarks,
_add_acl_sequence_numbers,
],
remediation_transform_callbacks=[
_safe_acl_remediation, # NEW
],
)Benefits:
- ✅ Follows established
post_load_callbackspattern (familiar to developers) - ✅ Platform-specific without coupling to core logic
- ✅ Full access to HConfig tree manipulation API
- ✅ Enables safe ACL remediation, BGP session protection, etc.
- ✅ Users can extend via driver inheritance
- ✅ Minimal code changes (~15 lines total)
- ✅ No breaking changes to existing API
Describe alternatives you've considered
-
Manual Post-Processing (Current Approach)
- Users write separate scripts to manipulate remediation output
- Cons: Code duplication, breaks driver cohesion, harder to share patterns
-
Declarative Remediation Transform Rules
- Add new rule types like
RemediationTransformRulewithtransform_typeenum - Pros: Fully declarative, serializable, type-safe
- Cons: Requires more upfront design, less flexible than callbacks
- Add new rule types like
-
Plugin System with Registration
- External plugin framework for user-defined remediation transforms
- Pros: Users can extend without modifying hier_config source
- Cons: Significant implementation overhead, may be premature
-
Workflow Subclassing
- Users subclass
WorkflowRemediationand overrideremediation_config - Cons: Doesn't scale, platform-specific logic should live in drivers
- Users subclass
The callback approach (Tier 1) provides immediate value with minimal changes, while leaving room for future enhancement to declarative rules or plugins if needed.
Additional context
Real-World Use Case: Safe ACL Remediation
# Running config
"""
ip access-list extended BLOCK_BAD
10 deny ip 192.0.2.0 0.0.0.255 any
12 deny ip any any
20 permit ip any any
"""
# Intended config
"""
ip access-list extended BLOCK_BAD
10 deny ip 192.0.2.0 0.0.0.255 any
15 permit tcp any any eq 443
20 permit ip any any
"""
# Standard remediation (UNSAFE - removes deny before adding permit)
"""
ip access-list extended BLOCK_BAD
no 12 deny ip any any
15 permit tcp any any eq 443
"""
# With remediation transform (SAFE)
"""
ip access-list extended BLOCK_BAD
1 permit ip any any # Safety net added first
no 12 deny ip any any # Remove problematic deny
15 permit tcp any any eq 443 # Add new permit
no 1 # Remove safety net
"""Other Potential Use Cases:
- BGP session protection (add peer shutdown before config changes, re-enable after)
- Route-map atomic updates (create new, switch reference, delete old)
- QoS policy safe transitions
- VLAN database modifications with traffic continuity
- Multi-step certificate/key rotations
Alignment with hier_config Design Philosophy:
- Declarative - Transforms are defined in driver rules
- Hierarchical - Operates on HConfig tree structure
- Composable - Multiple callbacks can be chained
- Platform Agnostic - Core workflow unchanged, platform-specific transforms in drivers
- Lazy Evaluation - Applied during property access, respects caching