diff --git a/filter_plugins/netbox.py b/filter_plugins/netbox.py index 0932c41..02ad61a 100644 --- a/filter_plugins/netbox.py +++ b/filter_plugins/netbox.py @@ -14,19 +14,36 @@ class FilterModule(object): 'iface_vlans': self.iface_vlans } - def compact_numlist(self, nums, sort=True, delimiter=',', range_delimiter='-'): - '''Transform [1,2,3,5,7,8,9] into "1-3,5,7-9"''' + def compact_numlist(self, nums, sort=True, delimiter=',', range_delimiter='-', max_per_line=None): + '''Transform [1,2,3,5,7,8,9] into "1-3,5,7-9". + + If max_per_line is given, return a list of such strings where each string contains at most max_per_line+1 numbers. + This emulates how VLAN ranges are displayed by FS switches so we can make ansible check mode work correctly. + ''' if sort: nums = sorted(nums) i = 0 - spans = [] + lines = [] + line = [] + nums_in_line = 0 while i < len(nums): j = i + 1 while j < len(nums) and nums[j]-nums[i] == j-i: j += 1 - spans += [f'{nums[i]}{range_delimiter}{nums[j-1]}' if j > i+1 else f'{nums[i]}'] + if j > i+1: + line += [f'{nums[i]}{range_delimiter}{nums[j-1]}'] + nums_in_line += 2 + else: + line += [f'{nums[i]}'] + nums_in_line += 1 + if max_per_line and nums_in_line >= max_per_line: + lines += [delimiter.join(line)] + line = [] + nums_in_line = 0 i = j - return delimiter.join(spans) + if line: + lines += [delimiter.join(line)] + return lines if max_per_line else lines[0] def device_address(self, device): '''Return loopback IP addresses for an L3 attached device''' diff --git a/roles/access/templates/config-fs.j2 b/roles/access/templates/config-fs.j2 index 6715715..b127495 100644 --- a/roles/access/templates/config-fs.j2 +++ b/roles/access/templates/config-fs.j2 @@ -6,7 +6,9 @@ no enable service telnet-server no enable service web-server http no enable service web-server https -vlan range {{ vlans | map(attribute='vid') | union([1]) | compact_numlist }} +{% for vlan_range in vlans | map(attribute='vid') | union([1]) | compact_numlist(max_per_line=19) %} +vlan range {{ vlan_range }} +{% endfor %} {% for iface in interfaces %} interface {{ iface.name }} @@ -37,6 +39,9 @@ interface {{ iface.name }} {%- elif iface.mode and iface.mode.value == 'tagged' %} switchport mode trunk switchport trunk allowed vlan only {{ (iface.tagged_vlans or vlans) | map(attribute='vid') | compact_numlist }} +{%- elif iface.mode and iface.mode.value == 'tagged-all' %} + switchport mode uplink + switchport trunk allowed vlan only 2-4094 {% endif %} {% endif %}