Skip to content

Commit

Permalink
Merge branch 'develop' into diff_run_framework
Browse files Browse the repository at this point in the history
  • Loading branch information
mikewiebe committed Aug 15, 2024
2 parents ca753a0 + 7d73e04 commit a3e296f
Show file tree
Hide file tree
Showing 39 changed files with 1,734 additions and 35 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ dmypy.json
# VSCode
.vscode/

# Mac OSX
*.DS_Store

# Ignore Roles Files Directories
roles/prepare_model/files
roles/dtc/common/files/*
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ interface_delete_mode: false
network_delete_mode: false
vrf_delete_mode: false
inventory_delete_mode: false
vpc_peering_delete_mode: false
vpc_delete_mode: false
link_vpc_delete_mode: false
```
**Note:** These variables are set to `false` by default to avoid accidental removal of configuration from NDFC that might impact the network.
Expand Down
7 changes: 3 additions & 4 deletions plugins/action/common/nac_dc_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import iac_validate.validator
from iac_validate.yaml import load_yaml_files
from iac_validate.cli.options import DEFAULT_SCHEMA
import os

display = Display()
Expand Down Expand Up @@ -65,10 +66,8 @@ def run(self, tmp=None, task_vars=None):
results['msg'] = "The data directory ({0}) for this fabric is empty!".format(mdata)
return results

if schema is None:
schema = ""
if rules is None:
rules = ""
if schema == '':
schema = DEFAULT_SCHEMA

validator = iac_validate.validator.Validator(schema, rules)
if schema:
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
requests
iac-validate<=0.2.4
iac-validate==0.2.5
iac-test==0.2.5
macaddress
macaddress
2 changes: 1 addition & 1 deletion roles/dtc/common/templates/ndfc_attach_vrfs.j2
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import_vpn_rt: {{ vrf['import_vpn_rt'] | default(omit) }}
netflow_enable: {{ vrf['netflow_enable'] | default(defaults.vxlan.overlay_services.vrfs.netflow_enable) }}
{% if vrf['netflow_enable'] is defined and vrf['netflow_enable'] | bool %}
netflow_monitor: {{ vrf['netflow_monitor'] }}
nf_monitor: {{ vrf['netflow_monitor'] }}
{% endif %}
no_rp: {{ vrf['no_rp'] | default(defaults.vxlan.overlay_services.vrfs.no_rp) }}
trm_enable: {{ vrf['trm_enable'] | default(defaults.vxlan.overlay_services.vrfs.trm_enable) }}
Expand Down
82 changes: 73 additions & 9 deletions roles/validate/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,23 @@ defaults:
vtep_loopback_id: 1
interfaces:
topology_switch_access_interface:
description: 'NetAsCode Access Interface'
description: "NetAsCode Access Interface"
mtu: jumbo
speed: auto
enabled: true
access_vlan: 1
spanning_tree_portfast: true
enable_bpdu_guard: true
topology_switch_trunk_interface:
description: 'NetAsCode Trunk Interface'
description: "NetAsCode Trunk Interface"
mtu: jumbo
speed: auto
enabled: true
trunk_allowed_vlans: none
spanning_tree_portfast: true
enable_bpdu_guard: true
topology_switch_access_po_interface:
description: 'NetAsCode Access PO Interface'
description: "NetAsCode Access PO Interface"
mtu: jumbo
speed: auto
enabled: true
Expand All @@ -68,32 +68,32 @@ defaults:
spanning_tree_portfast: true
enable_bpdu_guard: true
topology_switch_trunk_po_interface:
description: 'NetAsCode Trunk PO Interface'
mtu: jumbo
description: "NetAsCode Trunk PO Interface"
mtu: jumbo
speed: auto
enabled: true
trunk_allowed_vlans: none
pc_mode: active
spanning_tree_portfast: true
enable_bpdu_guard: true
topology_switch_routed_interface:
description: 'NetAsCode Routed Interface'
description: "NetAsCode Routed Interface"
mtu: 9216
speed: auto
enabled: true
topology_switch_routed_sub_interface:
description: 'NetAsCode Routed Sub Interface'
description: "NetAsCode Routed Sub Interface"
mtu: 9216
speed: auto
enabled: true
topology_switch_routed_po_interface:
description: 'NetAsCode Routed PO Interface'
description: "NetAsCode Routed PO Interface"
mtu: 9216
speed: auto
enabled: true
pc_mode: active
topology_switch_loopback_interface:
description: 'NetAsCode Loopback Interface'
description: "NetAsCode Loopback Interface"
enabled: true
vpc_peers:
domain_id: 1
Expand Down Expand Up @@ -170,6 +170,7 @@ defaults:
disable_rt_auto: false
netflow_enable: false
no_rp: false
rp_external: false
redist_direct_routemap: FABRIC-RMAP-REDIST-SUBNET
trm_enable: false
trm_bgw_msite: false
Expand All @@ -189,3 +190,66 @@ defaults:
network_attach_groups:
switches: []
overlay_extension:
vrf_lites:
ospf:
enabled: true
areas:
area_type: standard
auth_type: none
auth_key_id: 0
default_area: 0
distance: 110
bfd:
enabled: false
bgp:
enabled: true
best_path_as_path_relax: false
graceful_restart: true
graceful_restart_helper: false
address_family_ipv4_unicast:
additional_paths_receive: false
additional_paths_send: false
default_originate: false
ebgp_distance: 20
ibgp_distance: 200
local_distance: 220
max_paths_ebgp: 1
max_paths_ibgp: 1
max_paths_eibgp: 1
address_family_ipv6_unicast:
additional_paths_receive: false
additional_paths_send: false
default_originate: false
ebgp_distance: 20
ibgp_distance: 200
local_distance: 220
max_paths_ebgp: 1
max_paths_ibgp: 1
max_paths_eibgp: 1
switches:
interfaces:
ospf:
cost: 0
passive_interface: false
mtu_ignore: false
advertise_subnet: false
bfd:
enabled: true
hello_interval: 10
dead_interval: 40
network_type: broadcast
priority: 1
lsa_interval: 5
lsa_retransmit_interval: 1
bgp_peers:
allowas_in: false
allowas_in_as_number: 0
send_community: true
send_ext_community: true
as_override: false
next_hop_self: false
bfd:
enabled: true
disable_connected_check: false
remove_private_as: false
remove_private_as_all: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
class Rule:
id = "202"
description = "Verify Fabric Underlay Supports Multicast for TRM"
severity = "HIGH"

@classmethod
def match(cls, inventory):
results = []
fabric_replication = False
fabric_mcast_mode = False
fabric_trm = False

if inventory.get("vxlan", None):
if inventory["vxlan"].get("underlay", None):
if inventory["vxlan"].get("underlay").get("general", None):
fabric_replication = inventory["vxlan"]["underlay"]["general"].get("replication_mode", False)

if inventory["vxlan"].get("underlay").get("multicast", None):
fabric_mcast_mode = inventory["vxlan"]["underlay"]["multicast"].get("rp_mode", False)
fabric_trm = inventory["vxlan"]["underlay"]["multicast"].get("trm_enable", False)

if fabric_replication:
if ((fabric_replication == "multicast" and fabric_mcast_mode == "bidir" and fabric_trm) or
(fabric_replication == "ingress" and fabric_trm)):
results.append(
"For vxlan.underlay.multicast.trm_enable to be enabled, "
"vxlan.underlay.general.replication_mode must be set to multicast and "
"vxlan.underlay.multicast.rp_mode must be set to asm."
)

return results
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ def match(cls, inventory):
if inventory["vxlan"].get("global").get("netflow", None):
fabric_netflow_status = inventory["vxlan"]["global"]["netflow"].get("enable", False)

if inventory.get("vxlan", None):
if inventory["vxlan"].get("underlay", None):
if inventory["vxlan"].get("underlay").get("multicast", None):
fabric_trm_status = inventory["vxlan"]["underlay"]["multicast"].get("trm_enable", False)

if inventory.get("vxlan", None):
if inventory["vxlan"].get("overlay_services", None):
if inventory["vxlan"].get("overlay_services").get("vrfs", None):
vrfs = inventory["vxlan"]["overlay_services"]["vrfs"]
Expand All @@ -33,6 +31,17 @@ def match(cls, inventory):
f"For vxlan.overlay_services.vrfs.{vrf['name']}.netflow_enable to be enabled, "
f"first vxlan.global.netflow.enable must be enabled (true)."
)
break

if fabric_netflow_status and current_vrf_netflow_status:
current_vrf_netflow_monitor = vrf.get("netflow_monitor", None)
if current_vrf_netflow_monitor is None:
results.append(
f"When vxlan.overlay_services.vrfs.{vrf['name']}.netflow_enable is enabled, "
f"then vxlan.overlay_services.vrfs.{vrf['name']}.netflow_monitor must be set "
"to a valid value from vxlan.global.netflow."
)
break

current_vrf_trm_status = vrf.get("trm_enable", None)
if current_vrf_trm_status is not None:
Expand All @@ -41,5 +50,50 @@ def match(cls, inventory):
f"For vxlan.overlay_services.vrfs.{vrf['name']}.trm_enable to be enabled, "
f"first vxlan.underlay.multicast.trm_enable must be enabled (true)."
)
break

current_vrf_trm_no_rp = vrf.get("no_rp", None)
current_vrf_trm_rp_external = vrf.get("rp_external", None)
current_vrf_trm_rp_address = vrf.get("rp_address", None)
current_vrf_trm_rp_loopback_id = vrf.get("rp_loopback_id", None)
current_vrf_trm_underlay_mcast_ip = vrf.get("underlay_mcast_ip", None)
current_vrf_trm_overlay_multicast_group = vrf.get("overlay_multicast_group", None)

if fabric_trm_status:
if current_vrf_trm_no_rp and current_vrf_trm_underlay_mcast_ip is None:
results.append(
f"When vxlan.overlay_services.vrfs.{vrf['name']}.no_rp is enabled (true), "
f"then vxlan.overlay_services.vrfs.{vrf['name']}.underlay_mcast_ip must be set."
)
break

if (current_vrf_trm_no_rp and current_vrf_trm_rp_external or
current_vrf_trm_no_rp and current_vrf_trm_rp_address or
current_vrf_trm_no_rp and current_vrf_trm_rp_loopback_id or
current_vrf_trm_no_rp and current_vrf_trm_overlay_multicast_group):
results.append(
f"When vxlan.overlay_services.vrfs.{vrf['name']}.no_rp is enabled (true), "
f"then vxlan.overlay_services.vrfs.{vrf['name']}.rp_external, "
f"vxlan.overlay_services.vrfs.{vrf['name']}.rp_address, "
f"vxlan.overlay_services.vrfs.{vrf['name']}.rp_loopback_id, "
f"vxlan.overlay_services.vrfs.{vrf['name']}.overlay_multicast_group must be disabled (false)."
)
break

if current_vrf_trm_rp_external and current_vrf_trm_rp_loopback_id:
results.append(
f"When vxlan.overlay_services.vrfs.{vrf['name']}.rp_external is enabled (true), "
f"then vxlan.overlay_services.vrfs.{vrf['name']}.rp_loopback_id must be disabled (false)."
)
break

if (current_vrf_trm_rp_external and current_vrf_trm_rp_address is None or
current_vrf_trm_rp_external and current_vrf_trm_underlay_mcast_ip is None):
results.append(
f"When vxlan.overlay_services.vrfs.{vrf['name']}.rp_external is enabled (true), "
f"then vxlan.overlay_services.vrfs.{vrf['name']}.rp_address and "
f"vxlan.overlay_services.vrfs.{vrf['name']}.underlay_mcast_ip must be set."
)
break

return results
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@ class Rule:
def match(cls, inventory):
results = []
fabric_netflow_status = False
fabric_trm_status = False
networks = []

if inventory.get("vxlan", None):
if inventory["vxlan"].get("global", None):
if inventory["vxlan"].get("global").get("netflow", None):
fabric_netflow_status = inventory["vxlan"]["global"]["netflow"].get("enable", False)

if inventory.get("vxlan", None):
if inventory["vxlan"].get("underlay", None):
if inventory["vxlan"].get("underlay").get("multicast", None):
fabric_trm_status = inventory["vxlan"]["underlay"]["multicast"].get("trm_enable", False)

if inventory.get("vxlan", None):
if inventory["vxlan"].get("overlay_services", None):
if inventory["vxlan"].get("overlay_services").get("networks", None):
Expand All @@ -27,5 +33,25 @@ def match(cls, inventory):
f"For vxlan.overlay_services.networks.{network['name']}.netflow_enable to be enabled, "
f"first vxlan.global.netflow.enable must be enabled (true)."
)
break

if fabric_netflow_status and current_network_netflow_status:
current_network_netflow_monitor = network.get("vlan_netflow_monitor", None)
if current_network_netflow_monitor is None:
results.append(
f"When vxlan.overlay_services.networks.{network['name']}.netflow_enable is enabled, "
f"then vxlan.overlay_services.networks.{network['name']}.vlan_netflow_monitor must be set "
"to a valid value from vxlan.global.netflow."
)
break

current_network_trm_status = network.get("trm_enable", None)
if current_network_trm_status is not None:
if fabric_trm_status is False and current_network_trm_status is True:
results.append(
f"For vxlan.overlay_services.networks.{network['name']}.trm_enable to be enabled, "
f"first vxlan.underlay.multicast.trm_enable must be enabled (true)."
)
break

return results
1 change: 1 addition & 0 deletions roles/validate/tasks/sub_main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
rules: "{{ enhanced_rules_path }}"
vars:
data_path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}"
when: enhanced_rules_path is defined and enhanced_rules_path
delegate_to: localhost

- name: Verify Connection to NDFC {{ ansible_host }} on Port {{ ansible_httpapi_port | default(443) }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,32 @@ vxlan:
- ip_address: 172.16.255.252
vrf: management
severity: 3
netflow:
enable: true
exporter:
- name: nac-exporter1
ip_address: 192.168.70.1
source_interface: eth1/11
udp_port: 2055
- name: nac-exporter2
ip_address: 192.168.70.1
vrf: management
source_interface: eth1/12
udp_port: 2055
record:
- name: nac-record1
template: netflow_ipv4_record
- name: nac-record2
template: netflow_l2_record
layer2: true
monitor:
- name: nac-monitor1
record: nac-record1
exporter1: nac-exporter1
- name: nac-monitor2
record: nac-record2
exporter1: nac-exporter1
exporter2: nac-exporter2
vpc:
peer_link_vlan: 3600
peer_keep_alive: management
Expand Down
Loading

0 comments on commit a3e296f

Please sign in to comment.