Commit 1580ccc
GCU generates suboptimal plan for CreateOnly paths (#4335)
* GCU generates suboptimal plan for CreateOnly paths
When GCU hits a CreateOnly entry that has changed, it generates a suboptimal
plan. One example is a simple change of:
```
[{"op": "replace", "path": "/MIRROR_SESSION/EVERFLOW_TUNNEL/dst_ip", "value": "200.1.1.203"}]
```
Should generate an optimal plan of:
```
[
[{"op": "remove", "path": "/ACL_RULE/EVERFLOW|RULE_1/MIRROR_INGRESS_ACTION"}],
[{"op": "remove", "path": "/MIRROR_SESSION"}],
[{"op": "add", "path": "/MIRROR_SESSION", "value": {"EVERFLOW_TUNNEL": {"dscp": "8", "dst_ip": "200.1.1.203", "src_ip": "100.1.1.1", "ttl": "255", "type": "ERSPAN"}}}]
[{"op": "add", "path": "/ACL_RULE/EVERFLOW|RULE_1/MIRROR_INGRESS_ACTION", "value": "EVERFLOW_TUNNEL"}]
]
```
But instead generates this plan (which removes all ACLs):
```
[
[{"op": "remove", "path": "/ACL_RULE/EVERFLOW|RULE_1/MIRROR_INGRESS_ACTION"}],
[{"op": "remove", "path": "/ACL_RULE/EVERFLOW|RULE_1"}],
[{"op": "add", "path": "/ACL_RULE/EVERFLOW|RULE_1", "value": {"PRIORITY": "1000"}}],
[{"op": "add", "path": "/ACL_RULE/EVERFLOW|RULE_1/MIRROR_INGRESS_ACTION", "value": "EVERFLOW_TUNNEL"}],
[{"op": "remove", "path": "/ACL_RULE"}],
[{"op": "add", "path": "/ACL_RULE", "value": {"EVERFLOW|RULE_1": {"PRIORITY": "1000", "IP_TYPE": "IP", "MIRROR_INGRESS_ACTION": "EVERFLOW_TUNNEL"}}}],
[{"op": "add", "path": "/ACL_RULE/DATAACL|RULE_1", "value": {"PRIORITY": "10"}}],
[{"op": "add", "path": "/ACL_RULE/DATAACL|RULE_1/DST_IP", "value": "192.168.1.1/32"}],
[{"op": "add", "path": "/ACL_RULE/DATAACL|RULE_1/IP_TYPE", "value": "IP"}],
[{"op": "add", "path": "/ACL_RULE/DATAACL|RULE_1/L4_DST_PORT", "value": "22"}],
[{"op": "remove", "path": "/ACL_RULE/EVERFLOW|RULE_1/MIRROR_INGRESS_ACTION"}],
[{"op": "remove", "path": "/ACL_RULE/EVERFLOW|RULE_1"}],
[{"op": "add", "path": "/ACL_RULE/EVERFLOW|RULE_1", "value": {"PRIORITY": "1000"}}],
[{"op": "add", "path": "/ACL_RULE/EVERFLOW|RULE_1/MIRROR_INGRESS_ACTION", "value": "EVERFLOW_TUNNEL"}],
[{"op": "remove", "path": "/ACL_RULE/DATAACL|RULE_1"}],
[{"op": "add", "path": "/ACL_RULE/DATAACL|RULE_1", "value": {"PRIORITY": "10"}}],
[{"op": "add", "path": "/ACL_RULE/DATAACL|RULE_1/DST_IP", "value": "192.168.1.1/32"}],
[{"op": "add", "path": "/ACL_RULE/DATAACL|RULE_1/IP_TYPE", "value": "IP"}],
[{"op": "add", "path": "/ACL_RULE/DATAACL|RULE_1/PACKET_ACTION", "value": "DROP"}],
[{"op": "add", "path": "/ACL_RULE/EVERFLOW|RULE_1/IP_TYPE", "value": "IP"}],
[{"op": "remove", "path": "/ACL_RULE/EVERFLOW|RULE_1/MIRROR_INGRESS_ACTION"}],
[{"op": "remove", "path": "/ACL_RULE/EVERFLOW|RULE_1"}],
[{"op": "add", "path": "/ACL_RULE/EVERFLOW|RULE_1", "value": {"PRIORITY": "1000"}}],
[{"op": "remove", "path": "/ACL_RULE/DATAACL|RULE_1"}],
[{"op": "add", "path": "/ACL_RULE/EVERFLOW|RULE_1/IP_TYPE", "value": "IP"}],
[{"op": "add", "path": "/ACL_RULE/DATAACL|RULE_1", "value": {"PRIORITY": "10"}}],
[{"op": "add", "path": "/ACL_RULE/DATAACL|RULE_1/DST_IP", "value": "192.168.1.1/32"}],
[{"op": "add", "path": "/ACL_RULE/DATAACL|RULE_1/IP_TYPE", "value": "IP"}],
[{"op": "remove", "path": "/ACL_RULE/EVERFLOW|RULE_1"}],
[{"op": "add", "path": "/ACL_RULE/EVERFLOW|RULE_1", "value": {"PRIORITY": "1000"}}],
[{"op": "remove", "path": "/MIRROR_SESSION"}],
[{"op": "add", "path": "/MIRROR_SESSION", "value": {"EVERFLOW_TUNNEL": {"dscp": "8", "dst_ip": "200.1.1.203", "src_ip": "100.1.1.1", "ttl": "255", "type": "ERSPAN"}}}],
[{"op": "add", "path": "/ACL_RULE/DATAACL|RULE_1/L4_DST_PORT", "value": "22"}, {"op": "add", "path": "/ACL_RULE/DATAACL|RULE_1/PACKET_ACTION", "value": "DROP"}],
[{"op": "add", "path": "/ACL_RULE/EVERFLOW|RULE_1/IP_TYPE", "value": "IP"}, {"op": "add", "path": "/ACL_RULE/EVERFLOW|RULE_1/MIRROR_INGRESS_ACTION", "value": "EVERFLOW_TUNNEL"}]
]
```
Modified`RemoveCreateOnlyDependencyMoveGenerator`:
* it would previously short-circuit early due to only processing one child
leaf in the same table.
* it would previously attempt to iterate across all members of the table even
though there was a complete path list.
* it was missing logic to remove the create only path itself (and was relying
on extenders to do that which was inefficient and wouldn't generate the
right plan)
* when removing dependents it wasn't recursing to ensure it would remove
dependents of dependents
Since this generator is now full and doesn't rely on any extenders, it has
been moved to a non-extendable generator.
These changes caused some existing (suboptimal) plans that got generated to
change so those test cases have also been updated.
Added test case to validate this behavior and ensure it does not regress.
Signed-off-by: Brad House <bhouse@nexthop.ai>
* Update generic_config_updater/patch_sorter.py
Prevent possible infinite loop scenario Copilot identified,
however it shouldn't be possible given self.__get_path_count()
can't return 1 in that scenario to allow the loop to continue.
But hardening isn't a bad practice.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Brad House <bhouse@nexthop.ai>
* Update generic_config_updater/patch_sorter.py
Fix spelling / gramatical error caught by Copilot.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Brad House <bhouse@nexthop.ai>
* Code Review Comments
1. Add recursion depth protection in removing dependents because of
a concern of recursive dependencies, which isn't actually possible
with yang. None-the-less, implemented.
2. Remove a duplicate move that gets generated as when using it with a
Depth-first sorter its not necessary though could be on other sorters.
3. The old code depended on 3 levels of depth for the create only
leafs. Reworked the logic to not be dependent on depth.
4. __get_path_count() can no longer return a KeyError even though the
caller paths would make that impossible, but future use cases
may need it to not throw an exception when the path is not found.
Signed-off-by: Brad House <bhouse@nexthop.ai>
---------
Signed-off-by: Brad House <bhouse@nexthop.ai>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>1 parent 369e703 commit 1580ccc
File tree
3 files changed
+239
-108
lines changed- generic_config_updater
- tests/generic_config_updater
- files
3 files changed
+239
-108
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| |||
1580 | 1580 | | |
1581 | 1581 | | |
1582 | 1582 | | |
1583 | | - | |
1584 | 1583 | | |
1585 | 1584 | | |
1586 | | - | |
1587 | | - | |
1588 | | - | |
1589 | | - | |
1590 | | - | |
1591 | | - | |
1592 | | - | |
1593 | | - | |
1594 | | - | |
| 1585 | + | |
| 1586 | + | |
1595 | 1587 | | |
1596 | | - | |
1597 | | - | |
| 1588 | + | |
| 1589 | + | |
| 1590 | + | |
1598 | 1591 | | |
1599 | 1592 | | |
1600 | | - | |
1601 | | - | |
| 1593 | + | |
| 1594 | + | |
| 1595 | + | |
1602 | 1596 | | |
1603 | | - | |
1604 | | - | |
1605 | | - | |
| 1597 | + | |
| 1598 | + | |
| 1599 | + | |
| 1600 | + | |
1606 | 1601 | | |
1607 | | - | |
1608 | | - | |
1609 | | - | |
| 1602 | + | |
| 1603 | + | |
1610 | 1604 | | |
1611 | | - | |
1612 | | - | |
1613 | | - | |
1614 | | - | |
| 1605 | + | |
1615 | 1606 | | |
1616 | | - | |
1617 | | - | |
| 1607 | + | |
| 1608 | + | |
| 1609 | + | |
| 1610 | + | |
1618 | 1611 | | |
1619 | | - | |
| 1612 | + | |
| 1613 | + | |
| 1614 | + | |
| 1615 | + | |
| 1616 | + | |
1620 | 1617 | | |
1621 | | - | |
1622 | | - | |
1623 | | - | |
1624 | | - | |
| 1618 | + | |
| 1619 | + | |
| 1620 | + | |
| 1621 | + | |
| 1622 | + | |
| 1623 | + | |
| 1624 | + | |
| 1625 | + | |
| 1626 | + | |
| 1627 | + | |
| 1628 | + | |
| 1629 | + | |
| 1630 | + | |
| 1631 | + | |
| 1632 | + | |
| 1633 | + | |
| 1634 | + | |
| 1635 | + | |
| 1636 | + | |
| 1637 | + | |
| 1638 | + | |
| 1639 | + | |
| 1640 | + | |
| 1641 | + | |
| 1642 | + | |
| 1643 | + | |
| 1644 | + | |
| 1645 | + | |
| 1646 | + | |
| 1647 | + | |
| 1648 | + | |
| 1649 | + | |
| 1650 | + | |
1625 | 1651 | | |
1626 | | - | |
1627 | | - | |
| 1652 | + | |
| 1653 | + | |
| 1654 | + | |
| 1655 | + | |
| 1656 | + | |
| 1657 | + | |
| 1658 | + | |
| 1659 | + | |
| 1660 | + | |
| 1661 | + | |
| 1662 | + | |
| 1663 | + | |
1628 | 1664 | | |
1629 | | - | |
1630 | | - | |
1631 | | - | |
| 1665 | + | |
1632 | 1666 | | |
1633 | 1667 | | |
1634 | 1668 | | |
| |||
2222 | 2256 | | |
2223 | 2257 | | |
2224 | 2258 | | |
2225 | | - | |
2226 | | - | |
| 2259 | + | |
2227 | 2260 | | |
2228 | | - | |
| 2261 | + | |
| 2262 | + | |
2229 | 2263 | | |
2230 | 2264 | | |
2231 | 2265 | | |
| |||
0 commit comments