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

Untagged infra networks #140

Merged
merged 1 commit into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
15 changes: 15 additions & 0 deletions networking_ccloud/common/config/config_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ class InfraNetwork(pydantic.BaseModel):
networks: List[str] = []
aggregates: List[str] = []
vni: pydantic.conint(gt=0, lt=2**24)

# note that untagged OpenStack network will take precedence over untagged infra networks
untagged: bool = False
dhcp_relays: List[str] = []

Expand Down Expand Up @@ -327,6 +329,19 @@ def ensure_at_least_one_member(cls, v):
raise ValueError("Hostgroup needs to have at least one member")
return v

@pydantic.validator('infra_networks')
def ensure_only_one_untagged_infra_network(cls, v):
untagged_net = None
for infra_net in v or []:
if not infra_net.untagged:
continue
if untagged_net is None:
untagged_net = infra_net.name
else:
raise ValueError("Found two untagged InfraNetworks on same hostgroup: "
f"{untagged_net} and {infra_net.name}")
return v

@pydantic.root_validator()
def ensure_hostgroups_with_role_are_not_a_metagroup(cls, values):
# FIXME: constants? enum? what do we do here
Expand Down
4 changes: 3 additions & 1 deletion networking_ccloud/extensions/fabricoperations.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,9 @@ def sync_infra_networks(self, request, **kwargs):
scul = agent_msg.SwitchConfigUpdateList(agent_msg.OperationEnum.replace, self.drv_conf)
for hg in self.drv_conf.get_hostgroups_by_switches([switch.name]):
if hg.infra_networks:
scul.add_infra_networks_from_hostgroup(hg, sg)
# as we don't know if a direct-binding deployment is on a port we cannot
# process native vlans here --> needs to be done in a full switch sync
scul.add_infra_networks_from_hostgroup(hg, sg, process_untagged=False)
if hg.extra_vlans:
scul.add_extra_vlans(hg)
scul.clean_switches(switch.name)
Expand Down
18 changes: 11 additions & 7 deletions networking_ccloud/ml2/agent/common/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,8 @@ def get_or_create_switch(self, switch_name):
return self.switch_config_updates[switch_name]

def add_binding_host_to_config(self, hg_config, network_id, seg_vni, seg_vlan, trunk_vlan=None,
keep_mapping=False, exclude_hosts=None, is_bgw=False, gateways=None):
keep_mapping=False, exclude_hosts=None, is_bgw=False, gateways=None,
override_native=False):
"""Add binding host config to all required switches

Given a hostgroup config this method generates and adds config to this
Expand Down Expand Up @@ -422,10 +423,13 @@ def add_binding_host_to_config(self, hg_config, network_id, seg_vni, seg_vlan, t
iface = scu.get_or_create_iface_from_switchport(sp)
iface.add_trunk_vlan(seg_vlan)

if hg_config.direct_binding and not hg_config.role:
if trunk_vlan:
iface.add_vlan_translation(seg_vlan, trunk_vlan)
elif not hg_config.allow_multiple_trunk_ports:
if not hg_config.role:
if hg_config.direct_binding:
if trunk_vlan:
iface.add_vlan_translation(seg_vlan, trunk_vlan)
elif not hg_config.allow_multiple_trunk_ports:
iface.native_vlan = seg_vlan
elif not hg_config.direct_binding and override_native:
iface.native_vlan = seg_vlan

def add_vrf_bgp_config(self, switch_names, vrf_name, vrf_networks, vrf_aggregates):
Expand All @@ -447,15 +451,15 @@ def add_vrf_bgp_config(self, switch_names, vrf_name, vrf_networks, vrf_aggregate
aggregates.append(BGPVRFAggregate(network=network, az_local=az_local))
vrf.add_aggregates(aggregates)

def add_infra_networks_from_hostgroup(self, hg_config, sg):
def add_infra_networks_from_hostgroup(self, hg_config, sg, process_untagged=False):
for inet in hg_config.infra_networks or []:
# FIXME: exclude hosts
gateways = None
if inet.vrf:
gateways = {'vrf': inet.vrf, 'ips': inet.networks}

self.add_binding_host_to_config(hg_config, inet.name, inet.vni, inet.vlan,
gateways=gateways)
gateways=gateways, override_native=inet.untagged and process_untagged)

if inet.vrf:
# get network address from network (clear host bits); they are az-local and non-ext-announcable
Expand Down
2 changes: 1 addition & 1 deletion networking_ccloud/ml2/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def make_switchgroup_config(self, context, sg):
# add interconnects, infra networks and extra vlans
for hg in self.drv_conf.get_hostgroups_by_switches([sw.name for sw in sg.members]):
if hg.infra_networks:
scul.add_infra_networks_from_hostgroup(hg, sg)
scul.add_infra_networks_from_hostgroup(hg, sg, process_untagged=True)
if hg.extra_vlans:
scul.add_extra_vlans(hg)
if hg.role:
Expand Down
10 changes: 10 additions & 0 deletions networking_ccloud/tests/unit/common/test_driver_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,16 @@ def test_infra_network_vrf_presence(self):
config.DriverConfig, switchgroups=[switchgroup], hostgroups=hostgroups,
global_config=global_config)

def test_hostgroup_no_two_untagged_networks(self):
sg = cfix.make_switchgroup("seagull", availability_zone="qa-de-1a"),
untagged_1 = config.InfraNetwork(name="mew-gull", vlan=23, vni=100023, untagged=True)
untagged_2 = config.InfraNetwork(name="herring-gull", vlan=42, vni=100042, untagged=True)
regular_1 = config.InfraNetwork(name="sparrow", vlan=2, vni=2)
cfix.make_hostgroups(sg, infra_networks=[untagged_1])
cfix.make_hostgroups(sg, infra_networks=[untagged_1, regular_1])
self.assertRaisesRegex(ValueError, "on same hostgroup: mew-gull and herring-gull",
cfix.make_hostgroups, sg, infra_networks=[untagged_1, regular_1, untagged_2])

def test_duplicate_vrf_name(self):
vrfs = cfix.make_vrfs(['ROUTE-ME', 'ROUTE-ME'])

Expand Down
Loading