Skip to content

Commit 269c3cc

Browse files
Fix ACLs config drift issue (#563)
* Fix ACLs config drift issue Signed-off-by: rohitthakur2590 <[email protected]> * update tests Signed-off-by: rohitthakur2590 <[email protected]> * fix sanity Signed-off-by: rohitthakur2590 <[email protected]> * fix sanity Signed-off-by: rohitthakur2590 <[email protected]> * fix sanity Signed-off-by: rohitthakur2590 <[email protected]> * fix sanity Signed-off-by: rohitthakur2590 <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Signed-off-by: rohitthakur2590 <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 93c965a commit 269c3cc

File tree

5 files changed

+43
-26
lines changed

5 files changed

+43
-26
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
bugfixes:
3+
- Fixed an issue in the `compare_configs` method where unnecessary negate commands were generated for ACL entries already present in both `have` and `want` configurations.
4+
- Improved validation logic for ACL sequence numbers and content matching to ensure idempotency.
5+
- Prevented redundant configuration updates for Access Control Lists.

plugins/module_utils/network/eos/config/acls/acls.py

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -140,37 +140,53 @@ def compare_configs(self, have, want):
140140
commands = []
141141
want = list(itertools.chain(*want))
142142
have = list(itertools.chain(*have))
143+
144+
# Flatten the configurations for comparison
143145
h_index = 0
144-
config = list(want)
146+
config = list(want) # Start with a copy of `want`
147+
145148
for w in want:
146149
access_list = re.findall(r"(ip.*) access-list (.*)", w)
147150
if access_list:
151+
# Check if the whole ACL is already present
148152
if w in have:
149153
h_index = have.index(w)
150154
else:
155+
# Check sequence-specific entries
151156
for num, h in enumerate(have, start=h_index + 1):
152157
if "access-list" not in h:
153-
seq_num = re.search(r"(\d+) (.*)", w)
154-
if seq_num:
155-
have_seq_num = re.search(r"(\d+) (.*)", h)
156-
if seq_num.group(1) == have_seq_num.group(
157-
1,
158-
) and have_seq_num.group(
159-
2,
160-
) != seq_num.group(2):
161-
negate_cmd = "no " + seq_num.group(1)
162-
config.insert(config.index(w), negate_cmd)
163-
if w in h:
164-
config.pop(config.index(w))
165-
break
158+
snum = re.search(r"(\d+) (.*)", w)
159+
if snum:
160+
have_snum = re.search(r"(\d+) (.*)", h)
161+
if have_snum:
162+
snum_group_2 = snum.group(2)
163+
have_snum_group_2 = have_snum.group(2)
164+
# Match sequence number and full content
165+
if (
166+
snum.group(1) == have_snum.group(1)
167+
and snum_group_2 == have_snum_group_2
168+
):
169+
# Entry already exists, skip
170+
config.remove(w)
171+
break
172+
else:
173+
have_snum = re.search(r"(\d+) (.*)", h)
174+
if have_snum:
175+
# Match sequence number and full content
176+
if w == have_snum.group(2):
177+
config.remove(w)
178+
break
179+
180+
# Generate commands for any remaining entries in `config`
166181
for c in config:
167182
access_list = re.findall(r"(ip.*) access-list (.*)", c)
168183
if access_list:
169184
acl_index = config.index(c)
170185
else:
171186
if config[acl_index] not in commands:
172-
commands.append(config[acl_index])
173-
commands.append(c)
187+
commands.append(config[acl_index]) # Add ACL definition
188+
commands.append(c) # Add ACL entry
189+
174190
return commands
175191

176192
def set_state(self, want, have):

tests/integration/targets/eos_acls/tests/common/deleted.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
Start eos_acls deleted integration tests ansible_connection={{ ansible_connection
55
}}
66

7+
- ansible.builtin.include_tasks: _remove_config.yaml
8+
79
- ansible.builtin.include_tasks: _populate.yaml
810

911
- ansible.builtin.set_fact:

tests/integration/targets/eos_acls/tests/common/merged.yaml

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -142,19 +142,12 @@
142142
acls:
143143
- name: test1
144144
aces:
145-
- sequence: 35
146-
log: true
147-
ttl:
148-
eq: 33
149-
source:
150-
any: true
145+
- remark: "Update acl"
151146
state: merged
152147

153148
- ansible.builtin.assert:
154149
that:
155150
- result.changed == true
156-
- result.commands|length == 3
157-
- "'no 35' in result.commands"
158-
- "'35 deny tcp any any ttl eq 33 log' in result.commands"
151+
- result.commands|length == 2
159152
always:
160153
- ansible.builtin.include_tasks: _remove_config.yaml

tests/unit/modules/network/eos/test_eos_acls.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ def test_eos_acls_merged_idempotent(self):
141141
source=dict(any="true"),
142142
destination=dict(any="true"),
143143
protocol=6,
144+
sequence=45,
144145
),
145146
],
146147
),
@@ -150,7 +151,7 @@ def test_eos_acls_merged_idempotent(self):
150151
state="merged",
151152
),
152153
)
153-
self.execute_module(changed=False, commands=[])
154+
result = self.execute_module(changed=False)
154155

155156
def test_eos_acls_replaced(self):
156157
set_module_args(

0 commit comments

Comments
 (0)