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

Initial MSD Support #249

Draft
wants to merge 75 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
a86f756
MSD sub-main changes
anramgop Nov 25, 2024
77532ee
MSD sub-main changes
anramgop Nov 25, 2024
d37cdc4
Added sub-main-common and service model validation
anramgop Nov 26, 2024
49dcb6d
Split validate and load functions
anramgop Nov 27, 2024
7ef9df8
Refactoring sub main common
anramgop Nov 27, 2024
0bd0e4f
MSD create role
anramgop Nov 27, 2024
075475e
Additional refactoring for MSD and VXLAN workflows
mikewiebe Dec 3, 2024
9a73ea9
updates for msd fabric templating
mtarking Dec 3, 2024
9fd9855
resolve conflicts
mtarking Dec 3, 2024
0a1b042
remove dup file
mtarking Dec 3, 2024
e413ba3
update create task for msd
mtarking Dec 3, 2024
a220edd
update create task for msd
mtarking Dec 3, 2024
87c8395
Add child fabrics logic
mikewiebe Dec 3, 2024
3b2ad70
Merge branch 'msd' of https://github.com/netascode/ansible-dc-vxlan i…
mikewiebe Dec 3, 2024
a1b5bbd
updated defaults
mtarking Dec 3, 2024
c81d63a
Merge branch 'msd' of github.com:netascode/ansible-dc-vxlan into msd
mtarking Dec 3, 2024
9070b83
Update prepare plugins
mikewiebe Dec 3, 2024
e7520ec
more work on msd & shift to overlay key from overlay_services but wit…
mtarking Dec 5, 2024
95730f2
Merge branch 'msd' of github.com:netascode/ansible-dc-vxlan into msd
mtarking Dec 5, 2024
58aca5a
Merge branch 'develop' into msd
mtarking Dec 5, 2024
f821779
updates for build and deployment of both single fabrics and msd fabrics
mtarking Dec 5, 2024
73abf69
chagnes from review with mike
mtarking Dec 5, 2024
becfbd5
update fabric name reference to use extended
mtarking Dec 5, 2024
b6cbb56
updats to msite templates
mtarking Dec 5, 2024
1e7af33
update to msd tempaltes and add conditional to only run child fabrics…
mtarking Dec 6, 2024
48019b0
first commit from hospital
mtarking Dec 9, 2024
15655e7
updates for remove child fabrics and isn
mtarking Dec 9, 2024
13c8ba6
updates to current msd workflow
mtarking Dec 11, 2024
88742d2
merge develop
mtarking Dec 11, 2024
1219609
update github templates
mtarking Dec 11, 2024
a33823f
fix pipeline errors
mtarking Dec 11, 2024
4eb8d41
fix pipeline errors
mtarking Dec 11, 2024
898fc20
fix deprecation error in pipeline
mtarking Dec 11, 2024
b0cb580
fix deprecation error in pipeline
mtarking Dec 11, 2024
58bb54a
fix deprecation error in pipeline
mtarking Dec 11, 2024
9ccf722
Fix prep_001 plugin for multisite
mikewiebe Dec 12, 2024
2e64830
Workflow fixes
mikewiebe Dec 13, 2024
597272d
Merge develop and cleanup
mikewiebe Dec 20, 2024
58dd0f0
Fix list defaults bug
mikewiebe Dec 20, 2024
e7ef318
Prepare plugin refactor
mikewiebe Dec 21, 2024
e7ee3ff
More refactoring
mikewiebe Dec 22, 2024
7c31491
Initialize shared dict vars
mikewiebe Dec 22, 2024
6293b98
refactored external network into new format
mthurstocisco Jan 8, 2025
cffab66
more refactoring for external fabrics
mthurstocisco Jan 9, 2025
e019b74
bug fix in sub_main_external in common
mthurstocisco Jan 9, 2025
c2a0c48
External plus refactoring
mikewiebe Jan 10, 2025
4ab1f16
ISN remove devices and bug fixes
mikewiebe Jan 13, 2025
fdaa9d0
Enable child fabric delete mode flag
mikewiebe Jan 14, 2025
e765809
Github actions fixes
mikewiebe Jan 14, 2025
cde1ce4
GitHub Actions Issues
mikewiebe Jan 14, 2025
c6e6d3b
More GitHub Actions Fixes
mikewiebe Jan 14, 2025
5382ce2
Deploy False for Fabrics
mikewiebe Jan 15, 2025
57b7636
Refactor for sharing code and simplification
mikewiebe Jan 16, 2025
7d7a39f
Refactoring and Multisite VRF and Network Removal Flag
mikewiebe Jan 16, 2025
2fdcaa9
Merge branch 'develop' into msd
mikewiebe Jan 16, 2025
459d305
Fix route control no data
mikewiebe Jan 25, 2025
553df9e
Fix github actions issue
mikewiebe Jan 25, 2025
d948485
Fix rule 401
mikewiebe Jan 25, 2025
573184e
update defaults for msite
mtarking Jan 28, 2025
b7c3f28
fix typo
mtarking Jan 28, 2025
3b0a958
fix defaults
mtarking Jan 28, 2025
a0d2a08
refactor template groupings for vpc and vrf loopback
mtarking Jan 28, 2025
650efef
fix to isn fabric template
mtarking Jan 28, 2025
3c9cc02
get fabric attributes, fix msd templates, & start work on mapping swi…
mtarking Jan 29, 2025
0ef58cd
fix errors
mtarking Jan 29, 2025
938458d
refactor msite build for preprocessing for vrfs/networks attachments
mtarking Jan 30, 2025
f89bb1b
fix lint errors
mtarking Jan 30, 2025
2cd93f0
add msd child fabric vrfs template & fix lint errors
mtarking Jan 30, 2025
5627f6b
fixes
mtarking Jan 30, 2025
cf01600
set msite prepare defaults
mtarking Jan 30, 2025
116a424
Merge branch 'develop' into msd
mtarking Feb 1, 2025
81156d2
updated existing rules to allow empty vrfs & add first msite rule
mtarking Feb 2, 2025
5aa7677
fix lint errors
mtarking Feb 2, 2025
e29c17e
add msite cross-ref rule
mtarking Feb 2, 2025
fd4c73c
fix typo
mtarking Feb 2, 2025
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
Prev Previous commit
Next Next commit
more work on msd & shift to overlay key from overlay_services but wit…
…h backward compat.
  • Loading branch information
mtarking committed Dec 5, 2024
commit e7520ec582a95f6465ed5e9316d80c3a9a349e00
74 changes: 61 additions & 13 deletions plugins/action/common/nac_dc_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from ansible.errors import AnsibleError

try:
from iac_validate.yaml import load_yaml_files
import iac_validate.validator
from iac_validate.cli.options import DEFAULT_SCHEMA
except ImportError as imp_exc:
Expand All @@ -37,6 +38,7 @@
IAC_VALIDATE_IMPORT_ERROR = None

import os
from ...plugin_utils.helper_functions import data_model_key_check

display = Display()

Expand Down Expand Up @@ -77,18 +79,64 @@ def run(self, tmp=None, task_vars=None):
if schema == '':
schema = DEFAULT_SCHEMA

validator = iac_validate.validator.Validator(schema, rules)
if schema:
validator.validate_syntax([mdata])
if rules:
validator.validate_semantics([mdata])

msg = ""
for error in validator.errors:
msg += error + "\n"

if msg:
results['failed'] = True
results['msg'] = msg
rules_list = []
if rules and task_vars['role_path'] in rules:
# Load in-memory data model using iac-validate
# Perform the load in this if block to avoid loading the data model multiple times when custom enhanced rules are provided
results['data'] = load_yaml_files([mdata])

# Introduce common directory to the rules list by default once vrf and network rules are updated
# rules_to_run.append(f'{rules}common')
parent_keys = ['vxlan', 'fabric']
check = data_model_key_check(results['data'], parent_keys)
if 'fabric' in check['keys_found'] and 'fabric' in check['keys_data']:
if 'type' in results['data']['vxlan']['fabric']:
if results['data']['vxlan']['fabric']['type'] in ('VXLAN_EVPN'):
rules_list.append(f'{rules}vxlan/')
elif results['data']['vxlan']['fabric']['type'] in ('MSD', 'MCF'):
rules_list.append(f'{rules}multisite/')
else:
results['failed'] = True
results['msg'] = f"vxlan.fabric.type {results['data']['vxlan']['fabric']['type']} is not a supported fabric type."
else:
results['failed'] = True
results['msg'] = "vxlan.fabric.type is not defined in the data model."
else:
# This else block is to be removed after the deprecation of vxlan.global.fabric_type
parent_keys = ['vxlan', 'global']
check = data_model_key_check(results['data'], parent_keys)
if 'global' in check['keys_found'] and 'global' in check['keys_data']:
if 'fabric_type' in results['data']['vxlan']['global']:
display.deprecated("Attempting to use vxlan.global.fabric_type due to vxlan.fabric.type not being found. vxlan.global.fabric_type is being deprecated. Please use vxlan.fabric.type.")

if results['data']['vxlan']['global']['fabric_type'] in ('VXLAN_EVPN'):
rules_list.append(f'{rules}vxlan/')
elif results['data']['vxlan']['global']['fabric_type'] in ('MSD', 'MCF'):
rules_list.append(f'{rules}multisite/')
else:
results['failed'] = True
results['msg'] = f"vxlan.fabric.type {results['data']['vxlan']['global']['fabric_type']} is not a supported fabric type."
else:
results['failed'] = True
results['msg'] = "vxlan.fabric.type is not defined in the data model."
else:
# Else block to pickup custom enhanced rules provided by the user
rules_list.append(f'{rules}')

for rules_item in rules_list:
validator = iac_validate.validator.Validator(schema, rules_item)
if schema:
validator.validate_syntax([mdata])
if rules_item:
validator.validate_semantics([mdata])

msg = ""
for error in validator.errors:
msg += error + "\n"

if msg:
results['failed'] = True
results['msg'] = msg
break

return results
49 changes: 49 additions & 0 deletions plugins/action/common/prepare_plugins/prep_001_list_defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,55 @@ def prepare(self):
# Fabric Overlay List Defaults
# --------------------------------------------------------------------

# Check vxlan.overlay list elements
parent_keys = ['vxlan', 'overlay']
dm_check = data_model_key_check(self.model_data, parent_keys)
if 'overlay' in dm_check['keys_not_found'] or 'overlay_services' in dm_check['keys_no_data']:
self.model_data['vxlan']['overlay'] = {'vrfs': []}
self.model_data['vxlan']['overlay'] = {'vrf_attach_groups': []}
self.model_data['vxlan']['overlay'] = {'networks': []}
self.model_data['vxlan']['overlay'] = {'network_attach_groups': []}

# Check vxlan.overlay_services.vrfs list element
target_key = 'vrfs'
self.set_list_default(parent_keys, target_key)

# Check vxlan.overlay.vrf_attach_groups list element
target_key = 'vrf_attach_groups'
self.set_list_default(parent_keys, target_key)

# Check vxlan.overlay.vrf_attach_groups[index].switches list elements
list_index = 0
for group in self.model_data['vxlan']['overlay']['vrf_attach_groups']:
dm_check = data_model_key_check(group, ['switches'])
if 'switches' in dm_check['keys_not_found'] or \
'switches' in dm_check['keys_no_data']:
self.model_data['vxlan']['overlay']['vrf_attach_groups'][list_index]['switches'] = []

list_index += 1

# Check vxlan.overlay.networks list element
target_key = 'networks'
self.set_list_default(parent_keys, target_key)

# Check vxlan.overlay.network_attach_groups list element
target_key = 'network_attach_groups'
self.set_list_default(parent_keys, target_key)

# Check vxlan.overlay.network_attach_groups[index].switches list elements
list_index = 0
for group in self.model_data['vxlan']['overlay']['network_attach_groups']:
dm_check = data_model_key_check(group, ['switches'])
if 'switches' in dm_check['keys_not_found'] or \
'switches' in dm_check['keys_no_data']:
self.model_data['vxlan']['overlay']['network_attach_groups'][list_index]['switches'] = []

list_index += 1

# --------------------------------------------------------------------
# Fabric Overlay List Defaults - Backwards Compatibility
# --------------------------------------------------------------------

# Check vxlan.overlay_services list elements
parent_keys = ['vxlan', 'overlay_services']
dm_check = data_model_key_check(self.model_data, parent_keys)
Expand Down
109 changes: 109 additions & 0 deletions plugins/action/common/prepare_plugins/prep_101_fabric.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Copyright (c) 2024 Cisco Systems, Inc. and its affiliates
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# SPDX-License-Identifier: MIT

from ansible.utils.display import Display
from ....plugin_utils.helper_functions import data_model_key_check

display = Display()


class PreparePlugin:
def __init__(self, **kwargs):
self.kwargs = kwargs
self.keys = []

def prepare(self):
model_data = self.kwargs['results']['model_extended']

parent_keys = ['vxlan', 'fabric']
dm_check = data_model_key_check(model_data, parent_keys)
if 'fabric' in dm_check['keys_not_found'] or 'fabric' in dm_check['keys_no_data']:
display.deprecated(
"Attempting to use vxlan.global.name and vxlan.global.fabric_type due to vxlan.fabric.name and vxlan.fabric.type not being found. "
"vxlan.global.name and vxlan.global.fabric_type is being deprecated. Please use vxlan.fabric."
)

# Prepare the data model to ensure vxlan.fabric.name is set
# global_data_check = False
# parent_keys = ['vxlan', 'global']
# dm_check = data_model_key_check(model_data, parent_keys)
# if 'global' in dm_check['keys_found'] and 'global' in dm_check['keys_data']:
# parent_keys = ['vxlan', 'global', 'name']
# dm_check = data_model_key_check(model_data, parent_keys)
# if 'name' in dm_check['keys_found'] and 'name' in dm_check['keys_data']:
# model_data['vxlan']['fabric']['name'] = model_data['vxlan']['global']['name']
# else:
# global_data_check = True

# parent_keys = ['vxlan', 'global', 'fabric_type']
# dm_check = data_model_key_check(model_data, parent_keys)
# if 'fabric_type' in dm_check['keys_found'] and 'fabric_type' in dm_check['keys_data']:
# model_data['vxlan']['fabric']['type'] = model_data['vxlan']['global']['fabric_type']
# else:
# self.kwargs['results']['failed'] = True
# self.kwargs['results']['msg'] = "vxlan.fabric is not set in the model data."
# global_data_check = True
# else:
# self.kwargs['results']['failed'] = True
# self.kwargs['results']['msg'] = "vxlan.fabric is not set in the model data."

# if global_data_check:
# self.kwargs['results']['failed'] = True
# self.kwargs['results']['msg'] = "vxlan.fabric is not set in the model data."
# else:
# parent_keys = ['vxlan', 'fabric', 'name']
# dm_check = data_model_key_check(model_data, parent_keys)
# if 'name' in dm_check['keys_no_data'] or 'name' in dm_check['keys_not_found']:
# parent_keys = ['vxlan', 'global', 'name']
# dm_check = data_model_key_check(model_data, parent_keys)
# if 'name' in dm_check['keys_data']:
# # Insert warning about deprecation and where found
# model_data['vxlan']['fabric']['name'] = model_data['vxlan']['global']['name']
# else:
# self.kwargs['results']['failed'] = True
# self.kwargs['results']['msg'] = "vxlan.fabric.name is not set in the model data."

# # Prepare the data model to ensure vxlan.fabric.type is set
# parent_keys = ['vxlan', 'fabric', 'type']
# dm_check = data_model_key_check(model_data, parent_keys)
# if 'type' in dm_check['keys_no_data'] or 'name' in dm_check['keys_not_found']:
# parent_keys = ['vxlan', 'global', 'fabric_type']
# dm_check = data_model_key_check(model_data, parent_keys)
# if 'fabric_type' in dm_check['keys_data']:
# # Insert warning about deprecation and where found
# model_data['vxlan']['fabric']['type'] = model_data['vxlan']['global']['fabric_type']
# else:
# self.kwargs['results']['failed'] = True
# self.kwargs['results']['msg'] = "vxlan.fabric.type is not set in the model data."

# 1 - no fabric key data model
# 2a - fabric key data model with no data (i.e. no name or type) > semantic valdiation failure with schema
# 2b - fabric key data model with no data (i.e. name or type) > check if we have global name and global fabric_type


# insert comment to indicate this is a oneoff check for fabric key as this should really be done in a rule,
# but fabric name and key are foundational for the collection so we need to ensure it is set.
# this prepare plugin also helps retain backwards compatibility with the global fabric name and fabric_type keys previously used.

# Prepare the data model to ensure vxlan.fabric.name is set

self.kwargs['results']['model_extended'] = model_data
return self.kwargs['results']
30 changes: 0 additions & 30 deletions plugins/action/common/prepare_plugins/prep_101_global.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,56 @@ def prepare(self):
model_data = self.kwargs['results']['model_extended']
switches = model_data['vxlan']['topology']['switches']

# Rebuild sm_data['vxlan']['overlay']['vrf_attach_groups'] into
# a structure that is easier to use.
vrf_grp_name_list = []
model_data['vxlan']['overlay']['vrf_attach_groups_dict'] = {}
for grp in model_data['vxlan']['overlay']['vrf_attach_groups']:
model_data['vxlan']['overlay']['vrf_attach_groups_dict'][grp['name']] = []
vrf_grp_name_list.append(grp['name'])
for switch in grp['switches']:
model_data['vxlan']['overlay']['vrf_attach_groups_dict'][grp['name']].append(switch)
# If the switch is in the switch list and a hostname is used, replace the hostname with the management IP
for switch in model_data['vxlan']['overlay']['vrf_attach_groups_dict'][grp['name']]:
if any(sw['name'] == switch['hostname'] for sw in switches):
found_switch = next((item for item in switches if item["name"] == switch['hostname']))
if found_switch.get('management').get('management_ipv4_address'):
switch['hostname'] = found_switch['management']['management_ipv4_address']
elif found_switch.get('management').get('management_ipv6_address'):
switch['hostname'] = found_switch['management']['management_ipv6_address']

# Remove vrf_attach_group from vrf if the group_name is not defined
for vrf in model_data['vxlan']['overlay']['vrfs']:
if 'vrf_attach_group' in vrf:
if vrf.get('vrf_attach_group') not in vrf_grp_name_list:
del vrf['vrf_attach_group']

# Rebuild sm_data['vxlan']['overlay']['network_attach_groups'] into
# a structure that is easier to use.
net_grp_name_list = []
model_data['vxlan']['overlay']['network_attach_groups_dict'] = {}
for grp in model_data['vxlan']['overlay']['network_attach_groups']:
model_data['vxlan']['overlay']['network_attach_groups_dict'][grp['name']] = []
net_grp_name_list.append(grp['name'])
for switch in grp['switches']:
model_data['vxlan']['overlay']['network_attach_groups_dict'][grp['name']].append(switch)
# If the switch is in the switch list and a hostname is used, replace the hostname with the management IP
for switch in model_data['vxlan']['overlay']['network_attach_groups_dict'][grp['name']]:
if any(sw['name'] == switch['hostname'] for sw in switches):
found_switch = next((item for item in switches if item["name"] == switch['hostname']))
if found_switch.get('management').get('management_ipv4_address'):
switch['hostname'] = found_switch['management']['management_ipv4_address']
elif found_switch.get('management').get('management_ipv6_address'):
switch['hostname'] = found_switch['management']['management_ipv6_address']

# Remove network_attach_group from net if the group_name is not defined
for net in model_data['vxlan']['overlay']['networks']:
if 'network_attach_group' in net:
if net.get('network_attach_group') not in net_grp_name_list:
del net['network_attach_group']

# Backwards compatibility for vxlan.overlay_services

# Rebuild sm_data['vxlan']['overlay_services']['vrf_attach_groups'] into
# a structure that is easier to use.
vrf_grp_name_list = []
Expand Down
10 changes: 5 additions & 5 deletions roles/dtc/common/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@

---

- name: Import Role Tasks for MSD Fabric
ansible.builtin.import_tasks: sub_main_msd.yml
tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml
when: MD_Extended.vxlan.fabric_type == 'MSD'

- name: Import Role Tasks for VXLAN Fabric
ansible.builtin.import_tasks: sub_main_vxlan.yml
tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml
when: MD_Extended.vxlan.fabric_type == 'VXLAN_EVPN'

- name: Import Role Tasks for MSD Fabric
ansible.builtin.import_tasks: sub_main_msd.yml
tags: "{{ nac_tags.common_role }}" # Tags defined in roles/common_global/vars/main.yml
when: MD_Extended.vxlan.fabric_type == 'MSD'
1 change: 1 addition & 0 deletions roles/dtc/common/tasks/ndfc_fabric.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
{{ MD.vxlan.name }}_ndfc_fabric.yml
{% elif MD.vxlan.global.name is defined and MD.vxlan.global.name %}
{{ MD.vxlan.global.name }}_ndfc_fabric.yml
{% endif %}
delegate_to: localhost

- name: Stat Previous File If It Exists
Expand Down
2 changes: 1 addition & 1 deletion roles/dtc/common/tasks/sub_main_vxlan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
# --------------------------------------------------------------------

- name: Build Fabric Create Parameters
ansible.builtin.include_tasks: vxlan/ndfc_fabric.yml
ansible.builtin.include_tasks: ndfc_fabric.yml

# --------------------------------------------------------------------
# Build NDFC Fabric Switch Inventory List From Template
Expand Down
Loading