Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add virtual address to l3_interfaces fact #170

Merged
merged 7 commits into from
Feb 23, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -69,7 +69,11 @@
secondary:
description:
- Whether or not this address is a secondary address.
virtual:
description:
- Whether or not this address is a virtual address.
type: bool
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"])