Skip to content

Commit

Permalink
Add virtual address to l3_interfaces fact (#170)
Browse files Browse the repository at this point in the history
Add virtual address to l3_interfaces fact

Reviewed-by: https://github.com/apps/ansible-zuul
  • Loading branch information
GomathiselviS authored Feb 23, 2021
1 parent ba80571 commit 5b2d6ad
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 20 deletions.
3 changes: 3 additions & 0 deletions changelogs/fragments/add_virtual_interface.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
bugfixes:
- Add 'virtual' key to denote the existence of virtual address on an interface.(https://github.com/ansible-collections/arista.eos/pull/170).
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def __init__(self, **kwargs):
"options": {
"address": {"type": "str"},
"secondary": {"type": "bool"},
"virtual": {"type": "bool"},
},
"type": "list",
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ def _state_replaced(want, have):
if intf_commands:
commands.append("interface {0}".format(interface_name))
commands.extend(intf_commands)

return commands

@staticmethod
Expand All @@ -191,9 +190,9 @@ def _state_overridden(want, have):
desired = dict()
if desired.get("ipv4"):
for ipv4 in desired["ipv4"]:
if ipv4["secondary"] is None:
del ipv4["secondary"]

for k in ["secondary", "virtual"]:
if ipv4[k] is None:
del ipv4[k]
intf_commands = set_interface(desired, extant)
intf_commands.extend(clear_interface(desired, extant))

Expand Down Expand Up @@ -253,7 +252,6 @@ def _state_deleted(want, have):

def set_interface(want, have):
commands = []

want_ipv4 = set(
tuple(sorted(address.items())) for address in want.get("ipv4") or []
)
Expand All @@ -262,14 +260,17 @@ def set_interface(want, have):
)
for address in want_ipv4 - have_ipv4:
address = dict(address)
if "secondary" in address and not address["secondary"]:
del address["secondary"]
if tuple(address.items()) in have_ipv4:
continue
for param in ["secondary", "virtual"]:
if param in address and not address[param]:
del address[param]
if tuple(sorted(address.items())) in have_ipv4:
continue

address_cmd = "ip address {0}".format(address["address"])
if address.get("secondary"):
address_cmd += " secondary"
if address.get("virtual"):
address_cmd = "ip address virtual {0}".format(address["address"])
commands.append(address_cmd)

want_ipv6 = set(
Expand Down Expand Up @@ -297,14 +298,20 @@ def clear_interface(want, have):
else:
for address in have_ipv4 - want_ipv4:
address = dict(address)
if "secondary" not in address:
address["secondary"] = False
if tuple(address.items()) in want_ipv4:
continue
for param in ["secondary", "virtual"]:
if param not in address:
address[param] = None
if tuple(sorted(address.items())) in want_ipv4:
continue

if address.get("secondary"):
address_cmd = " {0} secondary".format(address["address"])
commands.append(address_cmd)
commands.append(
"no ip address {0} secondary".format(address["address"])
)
if address.get("virtual"):
commands.append(
"no ip address virtual {0}".format(address["address"])
)

if "secondary" not in address:
# Removing non-secondary removes all other interfaces
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,10 @@ def render_config(self, spec, conf):
config["ipv4"] = []
for match in matches:
address, dummy, remainder = match.partition(" ")
ipv4 = {"address": address}
if address == "virtual":
ipv4 = {"virtual": True, "address": remainder}
else:
ipv4 = {"address": address}
if remainder == "secondary":
ipv4["secondary"] = True
config["ipv4"].append(ipv4)
Expand Down
4 changes: 4 additions & 0 deletions plugins/modules/eos_l3_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@
description:
- Whether or not this address is a secondary address.
type: bool
virtual:
description:
- Whether or not this address is a virtual address.
type: bool
ipv6:
description:
- List of IPv6 addresses to be set for the Layer 3 interface mentioned in
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
interface Ethernet1
ip address 192.0.2.12/24
ip address 192.87.33.4/24 secondary
!
interface Ethernet2
ipv6 address 2001:db8::1/64
!
interface Management1
ip address dhcp
ipv6 address auto-config
!
interface Vlan100
ip address virtual 192.13.45.12/24
50 changes: 46 additions & 4 deletions tests/unit/modules/network/eos/test_eos_l3_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ def test_eos_l3_interfaces_merged(self):
name="Ethernet2",
ipv4=[dict(address="203.0.113.27/24")],
),
dict(
name="Vlan200",
ipv4=[dict(address="198.151.10.14/24", virtual=True)],
),
],
state="merged",
)
Expand All @@ -91,6 +95,8 @@ def test_eos_l3_interfaces_merged(self):
"ip address 198.51.100.14/24",
"interface Ethernet2",
"ip address 203.0.113.27/24",
"interface Vlan200",
"ip address virtual 198.151.10.14/24",
]
self.execute_module(changed=True, commands=commands)

Expand All @@ -99,11 +105,19 @@ def test_eos_l3_interfaces_merged_idempotent(self):
dict(
config=[
dict(
name="Ethernet1", ipv4=[dict(address="192.0.2.12/24")]
name="Ethernet1",
ipv4=[
dict(address="192.0.2.12/24"),
dict(address="192.87.33.4/24", secondary=True),
],
),
dict(
name="Ethernet2", ipv6=[dict(address="2001:db8::1/64")]
),
dict(
name="Vlan100",
ipv4=[dict(address="192.13.45.12/24", virtual=True)],
),
],
state="merged",
)
Expand Down Expand Up @@ -133,6 +147,8 @@ def test_eos_l3_interfaces_overridden(self):
"ip address 203.0.113.27/24",
"interface Ethernet1",
"no ip address",
"interface Vlan100",
"no ip address",
]
self.execute_module(changed=True, commands=commands)

Expand All @@ -144,13 +160,21 @@ def test_eos_l3_interfaces_overridden_idempotent(self):
name="Ethernet2", ipv6=[dict(address="2001:db8::1/64")]
),
dict(
name="Ethernet1", ipv4=[dict(address="192.0.2.12/24")]
name="Ethernet1",
ipv4=[
dict(address="192.0.2.12/24"),
dict(address="192.87.33.4/24", secondary=True),
],
),
dict(
name="Management1",
ipv4=[dict(address="dhcp")],
ipv6=[dict(address="auto-config")],
),
dict(
name="Vlan100",
ipv4=[dict(address="192.13.45.12/24", virtual=True)],
),
],
state="overridden",
)
Expand Down Expand Up @@ -184,13 +208,21 @@ def test_eos_l3_interfaces_replaced_idempotent(self):
name="Ethernet2", ipv6=[dict(address="2001:db8::1/64")]
),
dict(
name="Ethernet1", ipv4=[dict(address="192.0.2.12/24")]
name="Ethernet1",
ipv4=[
dict(address="192.0.2.12/24"),
dict(address="192.87.33.4/24", secondary=True),
],
),
dict(
name="Management1",
ipv4=[dict(address="dhcp")],
ipv6=[dict(address="auto-config")],
),
dict(
name="Vlan100",
ipv4=[dict(address="192.13.45.12/24", virtual=True)],
),
],
state="replaced",
)
Expand Down Expand Up @@ -258,12 +290,22 @@ def test_eos_l3_interfaces_gathered(self):
set_module_args(dict(state="gathered"))
result = self.execute_module(changed=False)
gather_list = [
{"name": "Ethernet1", "ipv4": [{"address": "192.0.2.12/24"}]},
{
"name": "Ethernet1",
"ipv4": [
{"address": "192.0.2.12/24"},
{"address": "192.87.33.4/24", "secondary": True},
],
},
{"name": "Ethernet2", "ipv6": [{"address": "2001:db8::1/64"}]},
{
"name": "Management1",
"ipv4": [{"address": "dhcp"}],
"ipv6": [{"address": "auto-config"}],
},
{
"ipv4": [{"address": "192.13.45.12/24", "virtual": True}],
"name": "Vlan100",
},
]
self.assertEqual(gather_list, result["gathered"])

0 comments on commit 5b2d6ad

Please sign in to comment.