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

Drop all compatibility for pre 17.6 fw versions #117

Merged
merged 2 commits into from
Nov 5, 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
1 change: 0 additions & 1 deletion asr1k_neutron_l3/common/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
cfg.IntOpt('nc_timeout', default=5, help='Netconf-YANG timeout, default 5s'),
cfg.StrOpt('user_name', default='admin', help='Netconf-YANG User'),
cfg.StrOpt('password', default='secret', help='Netconf-YANG Password'),
cfg.BoolOpt('use_bdvif', default=True, help='Use BD-VIF when supported by device firmware'),
]

ASR1K_OPTS = [
Expand Down
28 changes: 5 additions & 23 deletions asr1k_neutron_l3/models/asr1k_pair.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,7 @@


class ASR1KContextBase(object):
swagner-de marked this conversation as resolved.
Show resolved Hide resolved
@property
def use_bdvif(self):
return self.version_min_17_3

@property
def bd_iftype(self):
return "BD-VIF" if self.use_bdvif else "BDI"
pass


class FakeASR1KContext(ASR1KContextBase):
Expand All @@ -44,10 +38,8 @@ class FakeASR1KContext(ASR1KContextBase):
stable results
"""

def __init__(self, version_min_17_3=True, version_min_17_6=True, version_min_17_13=True, version_min_17_15=True,
def __init__(self, version_min_17_13=True, version_min_17_15=True,
has_stateless_nat=True):
self.version_min_17_3 = version_min_17_3
self.version_min_17_6 = version_min_17_6
self.version_min_17_13 = version_min_17_13
self.version_min_17_15 = version_min_17_15
self._has_stateless_nat = has_stateless_nat
Expand All @@ -58,23 +50,19 @@ def has_stateless_nat(self):


class ASR1KContext(ASR1KContextBase):
version_min_17_3 = property(lambda self: self._get_version_attr('_version_min_17_3'))
version_min_17_6 = property(lambda self: self._get_version_attr('_version_min_17_6'))
version_min_17_13 = property(lambda self: self._get_version_attr('_version_min_17_13'))
version_min_17_15 = property(lambda self: self._get_version_attr('_version_min_17_15'))
has_stateless_nat = property(lambda self: self._get_version_attr('_has_stateless_nat'))

def __init__(self, name, host, yang_port, nc_timeout, username, password, use_bdvif, insecure=True,
force_bdi=False, headers={}):
def __init__(self, name, host, yang_port, nc_timeout, username, password, insecure=True,
headers={}):
self.name = name
self.host = host
self.yang_port = yang_port
self.nc_timeout = nc_timeout
self.username = username
self.password = password
self._use_bdvif = use_bdvif
self.insecure = insecure
self.force_bdi = force_bdi
self.headers = headers
self.headers['content-type'] = headers.get('content-type', "application/yang-data+json")
self.headers['accept'] = headers.get('accept', "application/yang-data+json")
Expand Down Expand Up @@ -108,8 +96,6 @@ def _to_int_if_possible(d):

ver = tuple(_to_int_if_possible(d) for d in ver)

self._version_min_17_3 = ver >= (17, 3)
self._version_min_17_6 = ver >= (17, 6)
self._version_min_17_13 = ver >= (17, 13)
self._version_min_17_15 = ver >= (17, 15)
self._has_stateless_nat = ver >= (17, 4)
Expand All @@ -135,10 +121,6 @@ def wait_alive(self):
time.sleep(1)
return False

@property
def use_bdvif(self):
return self.version_min_17_3 and self._use_bdvif and not self.force_bdi

def mark_alive(self, alive):
if not alive:
LOG.debug("Device %s marked as dead, resetting version info", self.host)
Expand All @@ -164,7 +146,7 @@ def __setup(self):

for device_name, config in device_config.items():
asr1kctx = ASR1KContext(device_name, config.host, config.yang_port, config.nc_timeout,
config.user_name, config.password, config.use_bdvif,
config.user_name, config.password,
insecure=True)

self.contexts.append(asr1kctx)
10 changes: 1 addition & 9 deletions asr1k_neutron_l3/models/netconf_yang/access_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ def __parameters__(cls):
return [
{"key": "name", "id": True},
{'key': 'rules', 'yang-key': "access-list-seq-rule", 'type': [ACLRule], 'default': []},
{'key': 'drop_on_17_3', 'default': False},
]

@classmethod
Expand Down Expand Up @@ -132,9 +131,6 @@ def add_rule(self, rule):
self.rules.append(rule)

def to_dict(self, context):
if context.version_min_17_3 and self.drop_on_17_3:
return {ACLConstants.EXTENDED: {}}

entry = OrderedDict()
entry[ACLConstants.NAME] = self.name
# entry[ACLConstants.ACL_RULE]=self.rules
Expand All @@ -150,9 +146,6 @@ def to_dict(self, context):

@execute_on_pair()
def update(self, context):
if context.version_min_17_3 and self.drop_on_17_3:
return None

# we need to check if the ACL needs to be updated, if it does selectively delete,
# because we can't easily update individual rules
if len(self._internal_validate(context=context)) > 0:
Expand All @@ -170,8 +163,7 @@ def is_orphan(self, context, *args, **kwargs):
if self.policy_id:
return False

return context.version_min_17_3 and \
(self.drop_on_17_3 or self.name.startswith("PBR-") and self.neutron_router_id is not None) or \
return (self.name.startswith("PBR-") and self.neutron_router_id is not None) or \
super(AccessList, self).is_orphan(*args, context=context, **kwargs)


Expand Down
24 changes: 2 additions & 22 deletions asr1k_neutron_l3/models/netconf_yang/bgp.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from collections import OrderedDict

from asr1k_neutron_l3.common.utils import from_cidr, to_cidr
from asr1k_neutron_l3.models.netconf_yang.ny_base import NyBase, execute_on_pair, NC_OPERATION, YANG_TYPE
from asr1k_neutron_l3.models.netconf_yang.ny_base import NyBase, execute_on_pair, NC_OPERATION
from asr1k_neutron_l3.models.netconf_yang import xml_utils


Expand Down Expand Up @@ -82,14 +82,6 @@ def __parameters__(cls):
return [
{'key': 'asn', 'id': True, 'yang-key': 'id'},
{'key': 'vrf', 'yang-key': 'name'},
{'key': 'connected', 'yang-path': 'ipv4-unicast/redistribute', 'default': False,
'yang-type': YANG_TYPE.EMPTY},
{'key': 'static', 'yang-path': 'ipv4-unicast/redistribute', 'default': False,
'yang-type': YANG_TYPE.EMPTY},
{'key': 'connected', 'yang-path': 'ipv4-unicast/redistribute-vrf', 'default': False,
'yang-type': YANG_TYPE.EMPTY},
{'key': 'static', 'yang-path': 'ipv4-unicast/redistribute-vrf', 'default': False,
'yang-type': YANG_TYPE.EMPTY},
swagner-de marked this conversation as resolved.
Show resolved Hide resolved
{'key': 'networks_v4', 'yang-path': 'ipv4-unicast/network', 'yang-key': BGPConstants.WITH_MASK,
'type': [Network], 'default': []},
]
Expand Down Expand Up @@ -160,19 +152,7 @@ def to_dict(self, context):
xml_utils.OPERATION: NC_OPERATION.PUT,
}

REDIST_CONST = BGPConstants.REDISTRIBUTE_VRF if context.version_min_17_3 else BGPConstants.REDISTRIBUTE

# redistribute connected/static is only used with 16.9
if self.from_device or not context.version_min_17_3:
if self.connected or self.static:
vrf[BGPConstants.IPV4_UNICAST][REDIST_CONST] = {}
if self.connected:
vrf[BGPConstants.IPV4_UNICAST][REDIST_CONST][BGPConstants.CONNECTED] = ''
if self.static:
vrf[BGPConstants.IPV4_UNICAST][REDIST_CONST][BGPConstants.STATIC] = ''

# networks are currently only announced with 17.4
if self.networks_v4 and (self.from_device or context.version_min_17_3):
if self.networks_v4:
vrf[BGPConstants.IPV4_UNICAST][BGPConstants.NETWORK] = {
BGPConstants.WITH_MASK: [
net.to_dict(context) for net in sorted(self.networks_v4, key=lambda x: (x.number, x.mask))
Expand Down
12 changes: 1 addition & 11 deletions asr1k_neutron_l3/models/netconf_yang/copy_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@

class CopyConfig(NyBase):
COPY = """
<copy xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-rpc">
<_source>{source}</_source>
<_destination>{destination}</_destination>
</copy>"""

COPY_17_3 = """
<copy xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-rpc">
<source-drop-node-name>{source}</source-drop-node-name>
<destination-drop-node-name>{destination}</destination-drop-node-name>
Expand All @@ -30,11 +24,7 @@ def copy_config(self, context, source='running-config', destination='startup-con
entity=self.__class__.__name__,
action='copy').time():
with ConnectionManager(context=context) as connection:
if context.version_min_17_3:
COPY_CMD = self.COPY_17_3
else:
COPY_CMD = self.COPY
result = connection.rpc(COPY_CMD.format(source=source, destination=destination),
result = connection.rpc(self.COPY.format(source=source, destination=destination),
entity=self.__class__.__name__,
action='copy')
parsed = etree.fromstring(result._raw.encode())
Expand Down
89 changes: 12 additions & 77 deletions asr1k_neutron_l3/models/netconf_yang/l2_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
from collections import OrderedDict
from oslo_log import log as logging

from asr1k_neutron_l3.common import utils
from asr1k_neutron_l3.models.netconf_yang.ny_base import NC_OPERATION, NyBase, execute_on_pair
from asr1k_neutron_l3.models.netconf_yang import xml_utils
from asr1k_neutron_l3.plugins.db import asr1k_db
Expand Down Expand Up @@ -116,8 +115,6 @@ def __init__(self, *args, **kwargs):

def preflight(self, context):
"""Remove wrong interface membership for all BD-VIF members"""
if not context.version_min_17_3:
return

# go through all non-deleted member interfaces
for bdvif in self.bdvif_members:
Expand Down Expand Up @@ -165,28 +162,20 @@ def to_dict(self, context):
bddef = OrderedDict()
bddef[xml_utils.NS] = xml_utils.NS_CISCO_BRIDGE_DOMAIN
bddef[L2Constants.BRIDGE_DOMAIN_ID] = self.id

if context.version_min_17_3:
if context.use_bdvif:
bddef[L2Constants.MEMBER] = {
L2Constants.MEMBER_IFACE: [_m.to_dict(context)
for _m in sorted(self.if_members,
key=lambda _x: _x.interface)],
L2Constants.MEMBER_BDVIF: [_m.to_dict(context)
for _m in sorted(self.bdvif_members, key=attrgetter('name'))],
}
if self.has_complete_member_config:
bddef[L2Constants.MEMBER][xml_utils.OPERATION] = NC_OPERATION.PUT
else:
# This can be used for migrating back from new-style bridges, but might bring some problems
# if the bridge was never used as a new-stlye bridge
# bddef[L2Constants.MEMBER] = {xml_utils.OPERATION: NC_OPERATION.DELETE}
pass
bddef[L2Constants.MEMBER] = {
L2Constants.MEMBER_IFACE: [_m.to_dict(context)
for _m in sorted(self.if_members,
key=lambda _x: _x.interface)],
L2Constants.MEMBER_BDVIF: [_m.to_dict(context)
for _m in sorted(self.bdvif_members, key=attrgetter('name'))],
}
if self.has_complete_member_config:
bddef[L2Constants.MEMBER][xml_utils.OPERATION] = NC_OPERATION.PUT

return {L2Constants.BRIDGE_DOMAIN_BRIDGE_ID: bddef}

def _diff(self, context, device_config):
if context.use_bdvif and device_config and not self.has_complete_member_config:
if device_config and not self.has_complete_member_config:
# we don't know all bd-vif members - the diff should represent if
# the bd-vifs we know about are configured
neutron_bdvif_names = [_m.name for _m in self.bdvif_members]
Expand Down Expand Up @@ -402,8 +391,6 @@ def to_dict(self, context):
instance[L2Constants.ENCAPSULATION] = OrderedDict()
instance[L2Constants.ENCAPSULATION][L2Constants.DOT1Q] = dot1q
instance[L2Constants.REWRITE] = rewrite
if not context.use_bdvif:
instance[L2Constants.BRIDGE_DOMAIN] = bridge_domain

result = OrderedDict()
result[L2Constants.SERVICE_INSTANCE] = instance
Expand Down Expand Up @@ -438,61 +425,9 @@ def is_orphan(self, all_segmentation_ids, *args, **kwargs):
int(self.id) not in all_segmentation_ids


class LoopbackExternalInterface(ServiceInstance):
PORT_CHANNEL = "2"

def __init__(self, **kwargs):
kwargs['bridge_domain'] = kwargs.get('dot1q')
kwargs['dot1q'] = kwargs.get('dot1q')
super(LoopbackExternalInterface, self).__init__(**kwargs)

def to_dict(self, context):
if context.use_bdvif:
return {}
else:
return super(LoopbackExternalInterface, self).to_dict(context)

def is_orphan(self, all_segmentation_ids, all_bd_ids, context, *args, **kwargs):
# KeepBDUpInterface is included here, as they share a port-channel
return not context.use_bdvif and \
(utils.to_bridge_domain(asr1k_db.MIN_SECOND_DOT1Q) <= int(self.id) <=
utils.to_bridge_domain(asr1k_db.MAX_SECOND_DOT1Q) and
int(self.id) not in all_bd_ids) or \
context.use_bdvif and \
(asr1k_db.MIN_DOT1Q <= int(self.id) <= asr1k_db.MAX_DOT1Q and
int(self.id) not in all_segmentation_ids)


class LoopbackInternalInterface(ServiceInstance):
PORT_CHANNEL = "3"

def __init__(self, **kwargs):
super(LoopbackInternalInterface, self).__init__(**kwargs)

def to_dict(self, context):
if context.use_bdvif:
return {}
else:
return super(LoopbackInternalInterface, self).to_dict(context)

def is_orphan(self, all_bd_ids, context, *args, **kwargs):
return context.use_bdvif or \
(utils.to_bridge_domain(asr1k_db.MIN_SECOND_DOT1Q) <= int(self.id) <=
utils.to_bridge_domain(asr1k_db.MAX_SECOND_DOT1Q) and
int(self.id) not in all_bd_ids)


class KeepBDUpInterface(ServiceInstance):
PORT_CHANNEL = "2"

def __init__(self, **kwargs):
super(KeepBDUpInterface, self).__init__(**kwargs)

def to_dict(self, context):
if context.use_bdvif:
return super(KeepBDUpInterface, self).to_dict(context)
else:
return {}

def is_orphan(self, all_router_ids, all_segmentation_ids, all_bd_ids, context, *args, **kwargs):
raise NotImplementedError("This class' orphan check is handled by LoopbackExternalInterface")
return (asr1k_db.MIN_DOT1Q <= int(self.id) <= asr1k_db.MAX_DOT1Q and
int(self.id) not in all_segmentation_ids)
Loading
Loading