diff --git a/plugins/action/common/prepare_plugins/prep_004_calculate_md5_policies.py b/plugins/action/common/prepare_plugins/prep_004_calculate_md5_policies.py new file mode 100644 index 000000000..9527db4d7 --- /dev/null +++ b/plugins/action/common/prepare_plugins/prep_004_calculate_md5_policies.py @@ -0,0 +1,51 @@ +# Copyright (c) 2025 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 + +import hashlib +import os + + +class PreparePlugin: + def __init__(self, **kwargs): + self.kwargs = kwargs + self.keys = [] + + def prepare(self): + data_model = self.kwargs['results']['model_extended'] + + # Loop through policies and extract 'filename' when present and calculate md5 + policies = data_model['vxlan'].get('policy', []) + if policies: + for policy in policies['policies']: + filename = policy.get('filename') + + if filename: + abs_path = os.path.expanduser(filename) + + with open(abs_path, 'r', encoding='utf-8') as file: + data = file.read() + + md5 = hashlib.md5(data.encode()).hexdigest() + policy.update({'md5': md5}) + + self.kwargs['results']['model_extended'] = data_model + + return self.kwargs['results'] diff --git a/roles/validate/files/rules/common/501_policy_cross_reference.py b/roles/validate/files/rules/common/501_policy_cross_reference.py index 9f756d623..cf844f2df 100644 --- a/roles/validate/files/rules/common/501_policy_cross_reference.py +++ b/roles/validate/files/rules/common/501_policy_cross_reference.py @@ -1,3 +1,6 @@ +import os + + class Rule: id = "501" description = "Verify policy cross reference between policies, groups, and switches" @@ -17,6 +20,14 @@ def match(cls, data_model): for policy in policies: filename = policy.get("filename", None) + # Test if filename exists + if filename: + if not os.path.exists(os.path.expanduser(filename)): + results.append( + f"Filename {filename} does not exist in policy: {policy.get('name')} " + ) + break + if ((filename and policy.get("template_name", None) and policy.get("template_vars", None)) or (filename and policy.get("template_vars", None))): results.append( diff --git a/roles/validate/tasks/manage_model_files_current.yml b/roles/validate/tasks/manage_model_files_current.yml index f98a7a8e4..a129e6b3f 100644 --- a/roles/validate/tasks/manage_model_files_current.yml +++ b/roles/validate/tasks/manage_model_files_current.yml @@ -46,6 +46,13 @@ register: smd_golden_current delegate_to: localhost +# Read current extended service model data into a variable called 'data_model_extended_current' +- name: Read Current Extended Service Model Data from Host + ansible.builtin.include_vars: + file: "{{ role_path }}/files/{{ data_model_extended.vxlan.fabric.name }}_service_model_extended.json" + register: data_model_extended_current + delegate_to: localhost + - name: Display Model File Changes ansible.utils.fact_diff: before: "{{ smd_golden_previous }}" @@ -54,6 +61,14 @@ when: check_roles['save_previous'] delegate_to: localhost +- name: Display Extended Service Model File Changes + ansible.utils.fact_diff: + before: "{{ data_model_extended_previous }}" + after: "{{ data_model_extended_current }}" + register: data_model_extended_diff + when: check_roles['save_previous'] + delegate_to: localhost + - name: Mark All Stages Completed When No Model Changes Detected cisco.nac_dc_vxlan.common.run_map: data_model: "{{ data_model_extended }}" @@ -62,6 +77,8 @@ - check_roles['save_previous'] - smd_golden_diff.diff_lines | length == 0 - smd_golden_diff.diff_text | length == 0 + - data_model_extended_diff.diff_lines | length == 0 + - data_model_extended_diff.diff_text | length == 0 - run_map_read_result.diff_run is true - force_run_all is false|bool delegate_to: localhost @@ -79,6 +96,8 @@ - check_roles['save_previous'] - smd_golden_diff.diff_lines | length == 0 - smd_golden_diff.diff_text | length == 0 + - data_model_extended_diff.diff_lines | length == 0 + - data_model_extended_diff.diff_text | length == 0 - run_map_read_result.diff_run is true|bool - force_run_all is false|bool delegate_to: localhost diff --git a/roles/validate/tasks/manage_model_files_previous.yml b/roles/validate/tasks/manage_model_files_previous.yml index 3b32a0327..7a4660c7d 100644 --- a/roles/validate/tasks/manage_model_files_previous.yml +++ b/roles/validate/tasks/manage_model_files_previous.yml @@ -42,6 +42,14 @@ when: golden_stat.stat.exists and check_roles['save_previous'] delegate_to: localhost +# Read and store previous extended service model data into a variable called 'data_model_extended_previous' +- name: Read Previous Extended Service Model Data from Host + ansible.builtin.include_vars: + file: "{{ role_path }}/files/{{ data_model_extended.vxlan.fabric.name }}_service_model_extended.json" + register: data_model_extended_previous + when: extended_stat.stat.exists and check_roles['save_previous'] + delegate_to: localhost + # Rename golden file from previous run to append '_previous' to the filename - name: Move Golden Service Model Data Previous ansible.builtin.command: > diff --git a/tests/sanity/ignore-2.14.txt b/tests/sanity/ignore-2.14.txt index 9016f1154..e85357227 100644 --- a/tests/sanity/ignore-2.14.txt +++ b/tests/sanity/ignore-2.14.txt @@ -3,6 +3,7 @@ plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has plugins/action/common/prepare_plugins/prep_001_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_002_global.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_003_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_004_calculate_md5_policies.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_106_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation diff --git a/tests/sanity/ignore-2.15.txt b/tests/sanity/ignore-2.15.txt index 9016f1154..e85357227 100644 --- a/tests/sanity/ignore-2.15.txt +++ b/tests/sanity/ignore-2.15.txt @@ -3,6 +3,7 @@ plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has plugins/action/common/prepare_plugins/prep_001_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_002_global.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_003_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_004_calculate_md5_policies.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_106_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation diff --git a/tests/sanity/ignore-2.16.txt b/tests/sanity/ignore-2.16.txt index 9016f1154..e85357227 100644 --- a/tests/sanity/ignore-2.16.txt +++ b/tests/sanity/ignore-2.16.txt @@ -3,6 +3,7 @@ plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has plugins/action/common/prepare_plugins/prep_001_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_002_global.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_003_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_004_calculate_md5_policies.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_106_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation diff --git a/tests/sanity/ignore-2.17.txt b/tests/sanity/ignore-2.17.txt index 9016f1154..e85357227 100644 --- a/tests/sanity/ignore-2.17.txt +++ b/tests/sanity/ignore-2.17.txt @@ -3,6 +3,7 @@ plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has plugins/action/common/prepare_plugins/prep_001_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_002_global.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_003_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_004_calculate_md5_policies.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_106_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation diff --git a/tests/sanity/ignore-2.18.txt b/tests/sanity/ignore-2.18.txt index 49b8b7d29..db5c28a5b 100644 --- a/tests/sanity/ignore-2.18.txt +++ b/tests/sanity/ignore-2.18.txt @@ -3,6 +3,7 @@ plugins/action/common/nac_dc_validate.py action-plugin-docs # action plugin has plugins/action/common/prepare_plugins/prep_001_fabric.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_002_global.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_003_list_defaults.py action-plugin-docs # action plugin has no matching module to provide documentation +plugins/action/common/prepare_plugins/prep_004_calculate_md5_policies.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_104_topology_switches.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_105_fabric_overlay.py action-plugin-docs # action plugin has no matching module to provide documentation plugins/action/common/prepare_plugins/prep_106_topology_interfaces.py action-plugin-docs # action plugin has no matching module to provide documentation