├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── main.yml ├── .gitignore ├── .vscode └── settings.json ├── CHANGELOG.rst ├── LICENSE ├── README.md ├── __init__.py ├── dcnm-ut ├── docs ├── cisco.dcnm.dcnm_bootflash_module.rst ├── cisco.dcnm.dcnm_fabric_module.rst ├── cisco.dcnm.dcnm_httpapi.rst ├── cisco.dcnm.dcnm_image_policy_module.rst ├── cisco.dcnm.dcnm_image_upgrade_module.rst ├── cisco.dcnm.dcnm_image_upload_module.rst ├── cisco.dcnm.dcnm_interface_module.rst ├── cisco.dcnm.dcnm_inventory_module.rst ├── cisco.dcnm.dcnm_links_module.rst ├── cisco.dcnm.dcnm_log_module.rst ├── cisco.dcnm.dcnm_maintenance_mode_module.rst ├── cisco.dcnm.dcnm_network_module.rst ├── cisco.dcnm.dcnm_policy_module.rst ├── cisco.dcnm.dcnm_resource_manager_module.rst ├── cisco.dcnm.dcnm_rest_module.rst ├── cisco.dcnm.dcnm_service_node_module.rst ├── cisco.dcnm.dcnm_service_policy_module.rst ├── cisco.dcnm.dcnm_service_route_peering_module.rst ├── cisco.dcnm.dcnm_template_module.rst ├── cisco.dcnm.dcnm_vpc_pair_module.rst └── cisco.dcnm.dcnm_vrf_module.rst ├── galaxy.yml ├── meta └── runtime.yml ├── playbooks ├── files │ └── dynamic_inventory.py └── roles │ ├── dcnm_bootflash │ ├── create_files.yaml │ ├── dcnm_hosts.yaml │ ├── dcnm_tests.yaml │ └── nxos_vars.yaml │ ├── dcnm_fabric │ ├── dcnm_hosts.yaml │ └── dcnm_tests.yaml │ ├── dcnm_image_policy │ ├── dcnm_hosts.yaml │ └── dcnm_tests.yaml │ ├── dcnm_image_upgrade │ ├── dcnm_hosts.yaml │ └── dcnm_tests.yaml │ ├── dcnm_interface │ ├── dcnm_hosts.yaml │ └── dcnm_tests.yaml │ ├── dcnm_maintenance_mode │ ├── dcnm_hosts.yaml │ └── dcnm_tests.yaml │ ├── dcnm_network │ ├── ansible.cfg │ ├── dcnm_hosts.yaml │ └── dcnm_tests.yaml │ ├── dcnm_policy │ ├── dcnm_hosts.yaml │ └── dcnm_tests.yaml │ ├── dcnm_vrf │ ├── dcnm_hosts.yaml │ └── dcnm_tests.yaml │ └── ndfc_interface │ ├── ansible.cfg │ ├── ndfc_hosts.yaml │ └── ndfc_tests.yaml ├── plugins ├── README.md ├── __init__.py ├── action │ ├── __init__.py │ ├── dcnm_image_upgrade.py │ ├── dcnm_interface.py │ ├── dcnm_inventory.py │ ├── dcnm_vrf.py │ └── tests │ │ └── unit │ │ └── ndfc_pc_members_validate.py ├── httpapi │ ├── __init__.py │ └── dcnm.py ├── module_utils │ ├── __init__.py │ ├── bootflash │ │ ├── __init__.py │ │ ├── bootflash_files.py │ │ ├── bootflash_info.py │ │ ├── convert_file_info_to_target.py │ │ └── convert_target_to_params.py │ ├── common │ │ ├── __init__.py │ │ ├── api │ │ │ ├── __init__.py │ │ │ ├── api.py │ │ │ ├── api_nd.py │ │ │ ├── config │ │ │ │ ├── class_ep │ │ │ │ │ ├── class_ep.py │ │ │ │ │ └── v2 │ │ │ │ │ │ ├── sites │ │ │ │ │ │ └── sites.py │ │ │ │ │ │ └── v2.py │ │ │ │ ├── config.py │ │ │ │ └── federation │ │ │ │ │ ├── federation.py │ │ │ │ │ └── manager │ │ │ │ │ └── manager.py │ │ │ ├── login.py │ │ │ └── v1 │ │ │ │ ├── __init__.py │ │ │ │ ├── configtemplate │ │ │ │ ├── __init__.py │ │ │ │ ├── configtemplate.py │ │ │ │ └── rest │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── config │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── config.py │ │ │ │ │ └── templates │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ └── templates.py │ │ │ │ │ └── rest.py │ │ │ │ ├── fm │ │ │ │ ├── __init__.py │ │ │ │ └── fm.py │ │ │ │ ├── imagemanagement │ │ │ │ ├── __init__.py │ │ │ │ ├── imagemanagement.py │ │ │ │ └── rest │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── discovery │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── discovery.py │ │ │ │ │ ├── imagemgnt │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── bootflash │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ └── bootflash.py │ │ │ │ │ └── imagemgnt.py │ │ │ │ │ ├── imageupgrade │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── imageupgrade.py │ │ │ │ │ ├── packagemgnt │ │ │ │ │ └── packagemgnt.py │ │ │ │ │ ├── policymgnt │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── policymgnt.py │ │ │ │ │ ├── rest.py │ │ │ │ │ └── stagingmanagement │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── stagingmanagement.py │ │ │ │ ├── lan_fabric │ │ │ │ ├── __init__.py │ │ │ │ ├── lan_fabric.py │ │ │ │ └── rest │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── control │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── control.py │ │ │ │ │ ├── fabrics │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ └── fabrics.py │ │ │ │ │ └── switches │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ └── switches.py │ │ │ │ │ ├── inventory │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── inventory.py │ │ │ │ │ └── rest.py │ │ │ │ └── v1.py │ │ ├── controller_features.py │ │ ├── controller_version.py │ │ ├── conversion.py │ │ ├── ep │ │ │ └── nexus │ │ │ │ ├── api │ │ │ │ ├── api.py │ │ │ │ └── federation │ │ │ │ │ ├── federation.py │ │ │ │ │ └── v4 │ │ │ │ │ ├── federations │ │ │ │ │ └── federations.py │ │ │ │ │ ├── members │ │ │ │ │ └── members.py │ │ │ │ │ └── v4.py │ │ │ │ └── nexus.py │ │ ├── epp │ │ │ ├── api │ │ │ │ └── config │ │ │ │ │ ├── class_epp │ │ │ │ │ └── v2 │ │ │ │ │ │ └── sites │ │ │ │ │ │ └── epp_sites.py │ │ │ │ │ └── federation │ │ │ │ │ ├── epp_federation_members.py │ │ │ │ │ └── manager │ │ │ │ │ └── epp_federation_manager.py │ │ │ └── epp_login.py │ │ ├── exceptions.py │ │ ├── image_policies.py │ │ ├── log.py │ │ ├── log_v2.py │ │ ├── logging_config.json │ │ ├── maintenance_mode.py │ │ ├── maintenance_mode_info.py │ │ ├── merge_dicts.py │ │ ├── merge_dicts_v2.py │ │ ├── params_merge_defaults.py │ │ ├── params_merge_defaults_v2.py │ │ ├── params_validate.py │ │ ├── params_validate_v2.py │ │ ├── properties.py │ │ ├── response_handler.py │ │ ├── rest_send.py │ │ ├── rest_send_v2.py │ │ ├── results.py │ │ ├── sender_dcnm.py │ │ ├── sender_file.py │ │ ├── sender_requests.py │ │ └── switch_details.py │ ├── fabric │ │ ├── __init__.py │ │ ├── common.py │ │ ├── config_deploy.py │ │ ├── config_save.py │ │ ├── create.py │ │ ├── delete.py │ │ ├── fabric_details_v2.py │ │ ├── fabric_summary.py │ │ ├── fabric_types.py │ │ ├── param_info.py │ │ ├── query.py │ │ ├── replaced.py │ │ ├── ruleset.py │ │ ├── template_get.py │ │ ├── template_get_all.py │ │ ├── update.py │ │ └── verify_playbook_params.py │ ├── image_policy │ │ ├── __init__.py │ │ ├── create.py │ │ ├── delete.py │ │ ├── image_policies.py │ │ ├── params_spec.py │ │ ├── payload.py │ │ ├── query.py │ │ ├── replace.py │ │ └── update.py │ ├── image_upgrade │ │ ├── __init__.py │ │ ├── image_policy_attach.py │ │ ├── image_policy_detach.py │ │ ├── image_stage.py │ │ ├── image_upgrade.py │ │ ├── image_validate.py │ │ ├── install_options.py │ │ ├── params_spec.py │ │ ├── switch_issu_details.py │ │ └── wait_for_controller_done.py │ └── network │ │ └── dcnm │ │ ├── __init__.py │ │ ├── dcnm.py │ │ └── dcnm_vpc_pair_utils.py └── modules │ ├── __init__.py │ ├── dcnm_bootflash.py │ ├── dcnm_fabric.py │ ├── dcnm_image_policy.py │ ├── dcnm_image_upgrade.py │ ├── dcnm_image_upload.py │ ├── dcnm_interface.py │ ├── dcnm_inventory.py │ ├── dcnm_links.py │ ├── dcnm_log.py │ ├── dcnm_maintenance_mode.py │ ├── dcnm_network.py │ ├── dcnm_policy.py │ ├── dcnm_resource_manager.py │ ├── dcnm_rest.py │ ├── dcnm_service_node.py │ ├── dcnm_service_policy.py │ ├── dcnm_service_route_peering.py │ ├── dcnm_template.py │ ├── dcnm_vpc_pair.py │ └── dcnm_vrf.py ├── requirements.txt ├── test-requirements.txt ├── tests ├── .gitignore ├── config.yml ├── integration │ └── targets │ │ ├── dcnm_bootflash │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ ├── dcnm_bootflash_deleted_specific.yaml │ │ │ ├── dcnm_bootflash_deleted_wildcard.yaml │ │ │ ├── dcnm_bootflash_query_specific.yaml │ │ │ └── dcnm_bootflash_query_wildcard.yaml │ │ ├── dcnm_fabric │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ ├── dcnm_fabric_deleted_basic.yaml │ │ │ ├── dcnm_fabric_deleted_basic_ipfm.yaml │ │ │ ├── dcnm_fabric_deleted_basic_isn.yaml │ │ │ ├── dcnm_fabric_deleted_basic_lan_classic.yaml │ │ │ ├── dcnm_fabric_deleted_basic_msd.yaml │ │ │ ├── dcnm_fabric_deleted_basic_vxlan.yaml │ │ │ ├── dcnm_fabric_merged_basic.yaml │ │ │ ├── dcnm_fabric_merged_basic_ipfm.yaml │ │ │ ├── dcnm_fabric_merged_basic_isn.yaml │ │ │ ├── dcnm_fabric_merged_save_deploy.yaml │ │ │ ├── dcnm_fabric_merged_save_deploy_ipfm.yaml │ │ │ ├── dcnm_fabric_query_basic.yaml │ │ │ ├── dcnm_fabric_replaced_basic.yaml │ │ │ ├── dcnm_fabric_replaced_basic_ipfm.yaml │ │ │ ├── dcnm_fabric_replaced_basic_isn.yaml │ │ │ ├── dcnm_fabric_replaced_basic_vxlan.yaml │ │ │ ├── dcnm_fabric_replaced_basic_vxlan_site_id.yaml │ │ │ ├── dcnm_fabric_replaced_save_deploy.yaml │ │ │ └── dcnm_fabric_replaced_save_deploy_ipfm.yaml │ │ ├── dcnm_image_policy │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ ├── dcnm_image_policy_deleted.yaml │ │ │ ├── dcnm_image_policy_deleted_all_policies.yaml │ │ │ ├── dcnm_image_policy_merged.yaml │ │ │ ├── dcnm_image_policy_overridden.yaml │ │ │ ├── dcnm_image_policy_query.yaml │ │ │ └── dcnm_image_policy_replaced.yaml │ │ ├── dcnm_image_upgrade │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ ├── 00_setup_create_fabric.yaml │ │ │ ├── 01_setup_add_switches_to_fabric.yaml │ │ │ ├── 02_setup_replace_image_policies.yaml │ │ │ ├── deleted.yaml │ │ │ ├── deleted_1x_switch.yaml │ │ │ ├── merged_global_config.yaml │ │ │ ├── merged_override_global_config.yaml │ │ │ └── query.yaml │ │ ├── dcnm_image_upload │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ └── dcnm │ │ │ ├── dcnm_image_upload_delete.yaml │ │ │ ├── dcnm_image_upload_merge.yaml │ │ │ ├── dcnm_image_upload_override.yaml │ │ │ └── dcnm_image_upload_query.yaml │ │ ├── dcnm_interface │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ └── dcnm │ │ │ ├── dcnm_aa_fex_delete.yaml │ │ │ ├── dcnm_aa_fex_merge.yaml │ │ │ ├── dcnm_aa_fex_override.yaml │ │ │ ├── dcnm_aa_fex_query.yaml │ │ │ ├── dcnm_aa_fex_replace.yaml │ │ │ ├── dcnm_delete_deploy.yaml │ │ │ ├── dcnm_delete_diff_options.yaml │ │ │ ├── dcnm_eth_delete.yaml │ │ │ ├── dcnm_eth_merge.yaml │ │ │ ├── dcnm_eth_override.yaml │ │ │ ├── dcnm_eth_replace.yaml │ │ │ ├── dcnm_intf_misc.yaml │ │ │ ├── dcnm_intf_multi_intf_merge.yaml │ │ │ ├── dcnm_intf_multi_switches.yaml │ │ │ ├── dcnm_intf_no_optional_elems.yaml │ │ │ ├── dcnm_intf_override_specific_types.yaml │ │ │ ├── dcnm_intf_query.yaml │ │ │ ├── dcnm_intf_sanity.yml │ │ │ ├── dcnm_lo_delete.yaml │ │ │ ├── dcnm_lo_fabric.yaml │ │ │ ├── dcnm_lo_merge.yaml │ │ │ ├── dcnm_lo_mpls.yaml │ │ │ ├── dcnm_lo_override.yaml │ │ │ ├── dcnm_lo_replace.yaml │ │ │ ├── dcnm_old_format_pb.yaml │ │ │ ├── dcnm_pc_delete.yaml │ │ │ ├── dcnm_pc_merge.yaml │ │ │ ├── dcnm_pc_override.yaml │ │ │ ├── dcnm_pc_replace.yaml │ │ │ ├── dcnm_st_fex_delete.yaml │ │ │ ├── dcnm_st_fex_merge.yaml │ │ │ ├── dcnm_st_fex_override.yaml │ │ │ ├── dcnm_st_fex_query.yaml │ │ │ ├── dcnm_st_fex_replace.yaml │ │ │ ├── dcnm_sub_delete.yaml │ │ │ ├── dcnm_sub_merge.yaml │ │ │ ├── dcnm_sub_override.yaml │ │ │ ├── dcnm_sub_replace.yaml │ │ │ ├── dcnm_svi_delete.yaml │ │ │ ├── dcnm_svi_invalid_params.yaml │ │ │ ├── dcnm_svi_merge.yaml │ │ │ ├── dcnm_svi_override.yaml │ │ │ ├── dcnm_svi_query.yaml │ │ │ ├── dcnm_svi_replace.yaml │ │ │ ├── dcnm_vpc_delete.yaml │ │ │ ├── dcnm_vpc_merge.yaml │ │ │ ├── dcnm_vpc_override.yaml │ │ │ └── dcnm_vpc_replace.yaml │ │ ├── dcnm_inventory │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ └── dcnm │ │ │ ├── deleted.yaml │ │ │ ├── merged.yaml │ │ │ ├── overridden.yaml │ │ │ ├── poap.yaml │ │ │ ├── query.yaml │ │ │ ├── rma.yaml │ │ │ └── sanity.yaml │ │ ├── dcnm_links │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ └── dcnm │ │ │ ├── dcnm_links_inter_ipv6_delete.yaml │ │ │ ├── dcnm_links_inter_ipv6_merge.yaml │ │ │ ├── dcnm_links_inter_ipv6_modify.yaml │ │ │ ├── dcnm_links_inter_ipv6_replace.yaml │ │ │ ├── dcnm_links_inter_missing_params.yaml │ │ │ ├── dcnm_links_inter_numbered_delete.yaml │ │ │ ├── dcnm_links_inter_numbered_merge.yaml │ │ │ ├── dcnm_links_inter_numbered_modify.yaml │ │ │ ├── dcnm_links_inter_numbered_replace.yaml │ │ │ ├── dcnm_links_inter_query.yaml │ │ │ ├── dcnm_links_inter_template_change.yaml │ │ │ ├── dcnm_links_intra_ipv6_delete.yaml │ │ │ ├── dcnm_links_intra_ipv6_merge.yaml │ │ │ ├── dcnm_links_intra_ipv6_modify.yaml │ │ │ ├── dcnm_links_intra_ipv6_query.yaml │ │ │ ├── dcnm_links_intra_ipv6_replace.yaml │ │ │ ├── dcnm_links_intra_missing_params.yaml │ │ │ ├── dcnm_links_intra_numbered_delete.yaml │ │ │ ├── dcnm_links_intra_numbered_merge.yaml │ │ │ ├── dcnm_links_intra_numbered_modify.yaml │ │ │ ├── dcnm_links_intra_numbered_query.yaml │ │ │ ├── dcnm_links_intra_numbered_replace.yaml │ │ │ ├── dcnm_links_intra_numbered_template_change.yaml │ │ │ ├── dcnm_links_intra_unnumbered_delete.yaml │ │ │ ├── dcnm_links_intra_unnumbered_merge.yaml │ │ │ ├── dcnm_links_intra_unnumbered_modify.yaml │ │ │ ├── dcnm_links_intra_unnumbered_query.yaml │ │ │ ├── dcnm_links_intra_unnumbered_replace.yaml │ │ │ ├── dcnm_links_intra_unnumbered_template_change.yaml │ │ │ ├── dcnm_links_intra_vpc_delete.yaml │ │ │ ├── dcnm_links_intra_vpc_merge.yaml │ │ │ ├── dcnm_links_intra_vpc_modify.yaml │ │ │ ├── dcnm_links_intra_vpc_query.yaml │ │ │ ├── dcnm_links_intra_vpc_replace.yaml │ │ │ ├── dcnm_links_misc.yaml │ │ │ ├── dcnm_links_sanity.yaml │ │ │ └── xe-test-cases │ │ │ ├── dcnm_links_intra_xe_delete.yaml │ │ │ ├── dcnm_links_intra_xe_merge.yaml │ │ │ ├── dcnm_links_intra_xe_modify.yaml │ │ │ ├── dcnm_links_intra_xe_query.yaml │ │ │ └── dcnm_links_intra_xe_replace.yaml │ │ ├── dcnm_log │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ └── dcnm │ │ │ └── test_logging.yaml │ │ ├── dcnm_maintenance_mode │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ ├── 00_setup_fabrics_1x_rw.yaml │ │ │ ├── 00_setup_fabrics_2x_rw.yaml │ │ │ ├── 01_merged_maintenance_mode_deploy_no_wait_switch_level.yaml │ │ │ ├── 02_merged_normal_mode_deploy_no_wait_switch_level.yaml │ │ │ ├── 03_merged_maintenance_mode_deploy_no_wait_top_level.yaml │ │ │ ├── 04_merged_normal_mode_deploy_no_wait_top_level.yaml │ │ │ ├── 05_merged_maintenance_mode_deploy_wait_top_level.yaml │ │ │ ├── 06_merged_normal_mode_deploy_wait_top_level.yaml │ │ │ ├── 07_merged_maintenance_mode_deploy_wait_switch_level.yaml │ │ │ ├── 08_merged_normal_mode_deploy_wait_switch_level.yaml │ │ │ ├── 09_merged_maintenance_mode_no_deploy.yaml │ │ │ └── README.md │ │ ├── dcnm_network │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ └── dcnm │ │ │ ├── deleted.yaml │ │ │ ├── merged.yaml │ │ │ ├── overridden.yaml │ │ │ ├── query.yaml │ │ │ ├── replaced.yaml │ │ │ ├── sanity.yaml │ │ │ └── self-contained-tests │ │ │ ├── deleted_net_all.yaml │ │ │ ├── ingress_replication_networks.yaml │ │ │ ├── merged_net_all.yaml │ │ │ ├── overridden_net_all.yaml │ │ │ ├── replaced_net_all.yaml │ │ │ ├── scale.yaml │ │ │ ├── sm_dhcp_params.yaml │ │ │ ├── sm_dhcp_update.yaml │ │ │ ├── sm_mcast_params.yaml │ │ │ ├── sm_mcast_update.yaml │ │ │ ├── so_dhcp_update.yaml │ │ │ ├── so_mcast_update.yaml │ │ │ └── tor_ports_networks.yaml │ │ ├── dcnm_policy │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ └── dcnm │ │ │ ├── dcnm_policy_delete.yaml │ │ │ ├── dcnm_policy_merge.yaml │ │ │ ├── dcnm_policy_merge_multi_switch.yaml │ │ │ ├── dcnm_policy_merge_same_template.yaml │ │ │ ├── dcnm_policy_modify.yaml │ │ │ ├── dcnm_policy_query.yaml │ │ │ ├── dcnm_policy_sanity.yaml │ │ │ └── dcnm_policy_with_vars_merge.yaml │ │ ├── dcnm_resource_manager │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ └── dcnm │ │ │ ├── dcnm_res_manager_delete.yaml │ │ │ ├── dcnm_res_manager_invalid_params.yaml │ │ │ ├── dcnm_res_manager_merge.yaml │ │ │ ├── dcnm_res_manager_query.yaml │ │ │ └── dcnm_res_manager_sanity.yaml │ │ ├── dcnm_service_node │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ └── dcnm │ │ │ ├── deleted.yaml │ │ │ ├── merged.yaml │ │ │ ├── overridden.yaml │ │ │ ├── query.yaml │ │ │ ├── replaced.yaml │ │ │ └── sanity.yaml │ │ ├── dcnm_service_policy │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ └── dcnm │ │ │ ├── dcnm_service_policy_delete.yaml │ │ │ ├── dcnm_service_policy_merge.yaml │ │ │ ├── dcnm_service_policy_overridden.yaml │ │ │ ├── dcnm_service_policy_query.yaml │ │ │ ├── dcnm_service_policy_replace.yaml │ │ │ └── dcnm_service_policy_sanity.yaml │ │ ├── dcnm_service_route_peering │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ └── dcnm │ │ │ ├── .dcnm_service_route_peering_delete.yaml.swp │ │ │ ├── dcnm_service_route_peering_adc_po_change.yaml │ │ │ ├── dcnm_service_route_peering_delete.yaml │ │ │ ├── dcnm_service_route_peering_fw_po_change.yaml │ │ │ ├── dcnm_service_route_peering_merge.yaml │ │ │ ├── dcnm_service_route_peering_merge_existing.yaml │ │ │ ├── dcnm_service_route_peering_no_opt_elems.yaml │ │ │ ├── dcnm_service_route_peering_no_state.yaml │ │ │ ├── dcnm_service_route_peering_override.yaml │ │ │ ├── dcnm_service_route_peering_query.yaml │ │ │ ├── dcnm_service_route_peering_replace.yaml │ │ │ └── dcnm_service_route_peering_sanity.yaml │ │ ├── dcnm_template │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ └── dcnm │ │ │ ├── dcnm_template_delete.yaml │ │ │ ├── dcnm_template_merge.yaml │ │ │ ├── dcnm_template_modify_properties.yaml │ │ │ ├── dcnm_template_no_delete.yaml │ │ │ ├── dcnm_template_query.yaml │ │ │ ├── dcnm_template_sanity.yaml │ │ │ ├── dcnm_template_validation_fail.yaml │ │ │ └── dcnm_template_wrong_state.yaml │ │ ├── dcnm_vpc_pair │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ └── dcnm │ │ │ ├── dcnm_vpc_pair_delete.yaml │ │ │ ├── dcnm_vpc_pair_merge.yaml │ │ │ ├── dcnm_vpc_pair_override.yaml │ │ │ ├── dcnm_vpc_pair_query.yaml │ │ │ └── dcnm_vpc_pair_replace.yaml │ │ ├── dcnm_vrf │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ └── dcnm │ │ │ ├── deleted.yaml │ │ │ ├── merged.yaml │ │ │ ├── overridden.yaml │ │ │ ├── query.yaml │ │ │ ├── replaced.yaml │ │ │ ├── sanity.yaml │ │ │ └── self-contained-tests │ │ │ ├── deleted_vrf_all.yaml │ │ │ ├── merged_vrf_all.yaml │ │ │ ├── overridden_vrf_all.yaml │ │ │ ├── replaced_vrf_all.yaml │ │ │ ├── scale.yaml │ │ │ └── vrf_lite.yaml │ │ ├── module_integration │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── meta │ │ │ └── main.yaml │ │ ├── tasks │ │ │ ├── dcnm.yaml │ │ │ ├── fabric_setup.yaml │ │ │ └── main.yaml │ │ └── tests │ │ │ ├── exec_vars │ │ │ └── vrfs.yaml │ │ │ ├── spine_leaf_basic.yaml │ │ │ ├── spine_leaf_merged.yaml │ │ │ ├── spine_leaf_overridden.yaml │ │ │ ├── spine_leaf_replaced.yaml │ │ │ └── spine_leaf_replaced_2.yaml │ │ ├── ndfc_interface │ │ ├── defaults │ │ │ └── main.yaml │ │ ├── files │ │ │ └── .gitkeep │ │ ├── tasks │ │ │ └── main.yaml │ │ ├── templates │ │ │ ├── ndfc_pc_create.j2 │ │ │ ├── ndfc_pc_interfaces.j2 │ │ │ └── ndfc_pc_members.j2 │ │ └── tests │ │ │ └── ndfc_pc_members.yaml │ │ ├── prepare_dcnm_intf │ │ └── tasks │ │ │ └── main.yaml │ │ ├── prepare_dcnm_links │ │ └── tasks │ │ │ └── main.yaml │ │ ├── prepare_dcnm_policy │ │ └── tasks │ │ │ └── main.yaml │ │ ├── prepare_dcnm_service_policy │ │ └── tasks │ │ │ └── main.yaml │ │ ├── prepare_dcnm_service_route_peering │ │ └── tasks │ │ │ └── main.yaml │ │ ├── prepare_dcnm_template │ │ └── tasks │ │ │ └── main.yaml │ │ └── prepare_dcnm_vpc_pair │ │ └── tasks │ │ └── main.yaml ├── sanity │ ├── ignore-2.10.txt │ ├── ignore-2.11.txt │ ├── ignore-2.12.txt │ ├── ignore-2.13.txt │ ├── ignore-2.14.txt │ ├── ignore-2.15.txt │ ├── ignore-2.16.txt │ └── ignore-2.9.txt └── unit │ ├── mocks │ ├── __init__.py │ ├── mock_fabric_details_by_name.py │ └── mock_switch_details.py │ ├── module_utils │ ├── __init__.py │ └── common │ │ ├── __init__.py │ │ ├── api │ │ ├── __init__.py │ │ ├── test_api_v1_configtemplate_rest_config_templates.py │ │ ├── test_api_v1_imagemanagement_rest_imagemgnt_bootflash.py │ │ ├── test_api_v1_imagemanagement_rest_imageupgrade.py │ │ ├── test_api_v1_imagemanagement_rest_policymgnt.py │ │ ├── test_api_v1_imagemanagement_rest_stagingmanagement.py │ │ ├── test_api_v1_lan_fabric_rest_control_fabrics.py │ │ └── test_api_v1_lan_fabric_rest_control_switches.py │ │ ├── common_utils.py │ │ ├── fixture.py │ │ ├── fixtures │ │ ├── merge_dicts.json │ │ ├── merge_dicts_v2.json │ │ ├── responses_ControllerFeatures.json │ │ ├── responses_DeployMaintenanceMode.json │ │ ├── responses_FabricDetailsByName.json │ │ ├── responses_MaintenanceMode.json │ │ ├── responses_SenderDcnm.json │ │ ├── responses_SwitchDetails.json │ │ ├── responses_ep_policies.json │ │ └── responses_ep_version.json │ │ ├── test_controller_features.py │ │ ├── test_controller_version.py │ │ ├── test_image_policies.py │ │ ├── test_log.py │ │ ├── test_log_v2.py │ │ ├── test_maintenance_mode.py │ │ ├── test_maintenance_mode_info.py │ │ ├── test_merge_dicts.py │ │ ├── test_merge_dicts_v2.py │ │ ├── test_params_validate.py │ │ ├── test_params_validate_v2.py │ │ ├── test_response_handler.py │ │ ├── test_rest_send_v2.py │ │ ├── test_sender_dcnm.py │ │ ├── test_sender_file.py │ │ └── test_switch_details.py │ └── modules │ └── dcnm │ ├── __init__.py │ ├── dcnm_bootflash │ ├── fixture.py │ ├── fixtures │ │ ├── configs_Deleted.json │ │ ├── configs_Query.json │ │ ├── file_info_ConvertFileInfoToTarget.json │ │ ├── payloads_BootflashFiles.json │ │ ├── responses_EpAllSwitches.json │ │ ├── responses_EpBootflashDiscovery.json │ │ ├── responses_EpBootflashFiles.json │ │ ├── responses_EpBootflashInfo.json │ │ ├── targets.json │ │ └── targets_ConvertFileInfoToTarget.json │ ├── test_bootflash_common.py │ ├── test_bootflash_deleted.py │ ├── test_bootflash_files.py │ ├── test_bootflash_info.py │ ├── test_bootflash_query.py │ ├── test_convert_file_info_to_target.py │ ├── test_convert_target_to_params.py │ └── utils.py │ ├── dcnm_fabric │ ├── fixture.py │ ├── fixtures │ │ ├── nv_pairs_VerifyPlaybookParams.json │ │ ├── payloads_FabricCommon.json │ │ ├── payloads_FabricCreate.json │ │ ├── payloads_FabricCreateBulk.json │ │ ├── payloads_FabricCreateCommon.json │ │ ├── payloads_FabricReplacedBulk.json │ │ ├── payloads_FabricUpdateBulk.json │ │ ├── payloads_VerifyPlaybookParams.json │ │ ├── responses_ConfigDeploy.json │ │ ├── responses_ConfigSave.json │ │ ├── responses_FabricCommon.json │ │ ├── responses_FabricCreate.json │ │ ├── responses_FabricCreateBulk.json │ │ ├── responses_FabricDelete.json │ │ ├── responses_FabricDetailsByName_V2.json │ │ ├── responses_FabricDetailsByNvPair_V2.json │ │ ├── responses_FabricDetails_V2.json │ │ ├── responses_FabricQuery.json │ │ ├── responses_FabricReplacedBulk.json │ │ ├── responses_FabricSummary.json │ │ ├── responses_FabricUpdateBulk.json │ │ ├── responses_ResponseHandler.json │ │ ├── responses_TemplateGet.json │ │ ├── responses_TemplateGetAll.json │ │ ├── responses_ep_fabric_config_deploy.json │ │ ├── responses_ep_fabric_config_save.json │ │ ├── templates_ParamInfo.json │ │ ├── templates_RuleSet.json │ │ └── templates_VerifyPlaybookParams.json │ ├── test_fabric_common.py │ ├── test_fabric_config_deploy.py │ ├── test_fabric_config_save.py │ ├── test_fabric_create.py │ ├── test_fabric_create_bulk.py │ ├── test_fabric_create_common.py │ ├── test_fabric_delete.py │ ├── test_fabric_details_by_name_v2.py │ ├── test_fabric_details_by_nv_pair_v2.py │ ├── test_fabric_details_v2.py │ ├── test_fabric_query.py │ ├── test_fabric_replaced_bulk.py │ ├── test_fabric_summary.py │ ├── test_fabric_types.py │ ├── test_fabric_update_bulk.py │ ├── test_param_info.py │ ├── test_ruleset.py │ ├── test_template_get.py │ ├── test_template_get_all.py │ ├── test_verify_playbook_params.py │ └── utils.py │ ├── dcnm_image_policy │ ├── fixture.py │ ├── fixtures │ │ ├── configs_Config2Payload.json │ │ ├── configs_Payload2Config.json │ │ ├── payloads_Config2Payload.json │ │ ├── payloads_ImagePolicyCreate.json │ │ ├── payloads_ImagePolicyCreateBulk.json │ │ ├── payloads_ImagePolicyReplaceBulk.json │ │ ├── payloads_ImagePolicyUpdate.json │ │ ├── payloads_ImagePolicyUpdateBulk.json │ │ ├── payloads_Payload2Config.json │ │ ├── response_current_RestSend.json │ │ ├── responses_EpPolicies.json │ │ ├── responses_EpPolicyCreate.json │ │ ├── responses_EpPolicyDelete.json │ │ ├── responses_EpPolicyEdit.json │ │ ├── responses_ImagePolicyCreate.json │ │ ├── responses_ImagePolicyCreateBulk.json │ │ ├── responses_ImagePolicyDelete.json │ │ ├── responses_ImagePolicyReplaceBulk.json │ │ ├── responses_ImagePolicyUpdate.json │ │ ├── responses_ImagePolicyUpdateBulk.json │ │ ├── result_current_RestSend.json │ │ ├── results_ImagePolicyCreateBulk.json │ │ ├── results_ImagePolicyDelete.json │ │ ├── results_ImagePolicyReplaceBulk.json │ │ ├── results_ImagePolicyTaskResult.json │ │ ├── results_ImagePolicyUpdate.json │ │ └── results_ImagePolicyUpdateBulk.json │ ├── test_image_policy_create.py │ ├── test_image_policy_create_bulk.py │ ├── test_image_policy_delete.py │ ├── test_image_policy_payload.py │ ├── test_image_policy_query.py │ ├── test_image_policy_replace_bulk.py │ ├── test_image_policy_update.py │ ├── test_image_policy_update_bulk.py │ └── utils.py │ ├── dcnm_image_upgrade │ ├── __init__.py │ ├── fixture.py │ ├── fixtures │ │ ├── devices_image_upgrade.json │ │ ├── image_upgrade_playbook_configs.json │ │ ├── image_upgrade_responses_ImagePolicyAction.json │ │ ├── image_upgrade_responses_ImageUpgradeCommon.json │ │ ├── image_upgrade_responses_SwitchDetails.json │ │ ├── payloads_ep_image_upgrade.json │ │ ├── responses_ep_image_stage.json │ │ ├── responses_ep_image_upgrade.json │ │ ├── responses_ep_image_validate.json │ │ ├── responses_ep_install_options.json │ │ ├── responses_ep_issu.json │ │ └── responses_ep_version.json │ ├── test_image_install_options.py │ ├── test_image_stage.py │ ├── test_image_upgrade.py │ ├── test_image_validate.py │ ├── test_switch_issu_details_by_device_name.py │ ├── test_switch_issu_details_by_ip_address.py │ ├── test_switch_issu_details_by_serial_number.py │ └── utils.py │ ├── dcnm_log │ ├── test_dcnm_log.py │ └── utils.py │ ├── dcnm_maintenance_mode │ ├── __init__.py │ ├── fixture.py │ ├── fixtures │ │ ├── configs_Common.json │ │ ├── configs_Merged.json │ │ ├── configs_Query.json │ │ ├── configs_Want.json │ │ ├── responses_EpAllSwitches.json │ │ ├── responses_EpFabrics.json │ │ ├── responses_EpMaintenanceModeDeploy.json │ │ ├── responses_EpMaintenanceModeDisable.json │ │ └── responses_EpMaintenanceModeEnable.json │ ├── test_dcnm_maintenance_mode_common.py │ ├── test_dcnm_maintenance_mode_merged.py │ ├── test_dcnm_maintenance_mode_params_spec.py │ ├── test_dcnm_maintenance_mode_query.py │ ├── test_dcnm_maintenance_mode_want.py │ └── utils.py │ ├── dcnm_module.py │ ├── fixtures │ ├── dcnm_image_upload_configs.json │ ├── dcnm_image_upload_payloads.json │ ├── dcnm_intf.json │ ├── dcnm_intf_aa_fex_configs.json │ ├── dcnm_intf_aa_fex_payloads.json │ ├── dcnm_intf_bunched_configs.json │ ├── dcnm_intf_common_configs.json │ ├── dcnm_intf_eth_configs.json │ ├── dcnm_intf_eth_payloads.json │ ├── dcnm_intf_have_all_payloads.json │ ├── dcnm_intf_lo_configs.json │ ├── dcnm_intf_lo_payloads.json │ ├── dcnm_intf_mixed_configs.json │ ├── dcnm_intf_multi_configs.json │ ├── dcnm_intf_multi_intf_configs.json │ ├── dcnm_intf_multi_intf_payloads.json │ ├── dcnm_intf_pc_configs.json │ ├── dcnm_intf_pc_have.json │ ├── dcnm_intf_pc_payloads.json │ ├── dcnm_intf_query_configs.json │ ├── dcnm_intf_query_payloads.json │ ├── dcnm_intf_st_fex_configs.json │ ├── dcnm_intf_st_fex_payloads.json │ ├── dcnm_intf_subint_configs.json │ ├── dcnm_intf_subint_payloads.json │ ├── dcnm_intf_svi_configs.json │ ├── dcnm_intf_svi_payloads.json │ ├── dcnm_intf_vpc_configs.json │ ├── dcnm_intf_vpc_payloads.json │ ├── dcnm_inventory.json │ ├── dcnm_links_configs.json │ ├── dcnm_links_payloads.json │ ├── dcnm_network.json │ ├── dcnm_policy_configs.json │ ├── dcnm_policy_payloads.json │ ├── dcnm_res_manager_configs.json │ ├── dcnm_res_manager_payloads.json │ ├── dcnm_service_node.json │ ├── dcnm_service_policy_configs.json │ ├── dcnm_service_policy_payloads.json │ ├── dcnm_srp_configs.json │ ├── dcnm_srp_payloads.json │ ├── dcnm_template_configs.json │ ├── dcnm_template_payloads.json │ ├── dcnm_vpc_pair │ │ ├── dcnm_vpc_pair_common.py │ │ ├── dcnm_vpc_pair_data.json │ │ └── dcnm_vpc_pair_response.json │ └── dcnm_vrf.json │ ├── test_dcnm_image_upload.py │ ├── test_dcnm_intf.py │ ├── test_dcnm_inventory.py │ ├── test_dcnm_links.py │ ├── test_dcnm_network.py │ ├── test_dcnm_policy.py │ ├── test_dcnm_res_manager.py │ ├── test_dcnm_service_node.py │ ├── test_dcnm_service_policy.py │ ├── test_dcnm_service_route_peering.py │ ├── test_dcnm_template.py │ ├── test_dcnm_vpc_pair.py │ └── test_dcnm_vrf.py └── tox.ini /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | 12 | ### Community Note 13 | 14 | * Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue to help the community and maintainers prioritize this request 15 | * Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request 16 | * If you are interested in working on this issue or have submitted a pull request, please leave a comment 17 | 18 | 19 | 20 | ### Ansible Version and collection version 21 | 22 | 23 | 24 | ### DCNM version 25 | 26 | * V x.x.x 27 | 28 | ### Affected module(s) 29 | 30 | 31 | 32 | * dcnm_XXXXX 33 | 34 | ### Ansible Playbook 35 | 36 | 37 | 38 | ```yaml 39 | # Copy-paste your anisble playbook here 40 | ``` 41 | 42 | ### Debug Output 43 | 44 | 49 | 50 | ### Expected Behavior 51 | 52 | 53 | 54 | ### Actual Behavior 55 | 56 | 57 | 58 | ### Steps to Reproduce 59 | 60 | 61 | 62 | ### References 63 | 64 | 69 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | 12 | ### Community Note 13 | 14 | * Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue to help the community and maintainers prioritize this request 15 | * Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request 16 | * If you are interested in working on this issue or have submitted a pull request, please leave a comment 17 | 18 | 19 | 20 | ### Description 21 | 22 | 23 | 24 | ### New or Affected modules(s): 25 | 26 | 27 | 28 | * dcnm_XXXXX 29 | 30 | ### DCNM version 31 | 32 | * V x.x.x 33 | 34 | ### Potential ansible task config 35 | 36 | 37 | 38 | ```yaml 39 | # Copy-paste your ansible playbook 40 | ``` 41 | 42 | ### References 43 | 44 | 50 | 51 | **Additional context** 52 | Add any other context or screenshots about the feature request here. 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Sphinx documentation 55 | docs/_build/ 56 | 57 | # PyBuilder 58 | target/ 59 | 60 | # Jupyter Notebook 61 | .ipynb_checkpoints 62 | 63 | # pyenv 64 | .python-version 65 | 66 | # Environments 67 | .env 68 | .venv 69 | env/ 70 | venv/ 71 | ENV/ 72 | env.bak/ 73 | venv.bak/ 74 | 75 | # mkdocs documentation 76 | /site 77 | 78 | # mypy 79 | .mypy_cache/ 80 | 81 | # Ignore Integration Tests Files Directories 82 | tests/integration/targets/ndfc_interface/files -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.testing.pytestArgs": ["tests"], 3 | "python.testing.unittestEnabled": false, 4 | "python.testing.pytestEnabled": true 5 | } 6 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/__init__.py -------------------------------------------------------------------------------- /dcnm-ut: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/dcnm-ut -------------------------------------------------------------------------------- /docs/cisco.dcnm.dcnm_httpapi.rst: -------------------------------------------------------------------------------- 1 | .. _cisco.dcnm.dcnm_httpapi: 2 | 3 | 4 | *************** 5 | cisco.dcnm.dcnm 6 | *************** 7 | 8 | **Ansible DCNM HTTPAPI Plugin.** 9 | 10 | 11 | Version added: 0.9.0 12 | 13 | .. contents:: 14 | :local: 15 | :depth: 1 16 | 17 | 18 | Synopsis 19 | -------- 20 | - This DCNM plugin provides the HTTPAPI transport methods needed to initiate a connection to the DCNM controller, send API requests and process the respsonse from the controller. 21 | 22 | 23 | 24 | 25 | Parameters 26 | ---------- 27 | 28 | .. raw:: html 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 46 | 49 | 53 | 57 | 58 |
ParameterChoices/DefaultsConfigurationComments
39 |
40 | login_domain 41 | 42 |
43 | string 44 |
45 |
47 | Default:
"local"
48 |
50 |
env:ANSIBLE_HTTPAPI_LOGIN_DOMAIN
51 |
var: ansible_httpapi_login_domain
52 |
54 |
The login domain name to use for user authentication
55 |
Only needed for NDFC
56 |
59 |
60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | Status 69 | ------ 70 | 71 | 72 | Authors 73 | ~~~~~~~ 74 | 75 | - Mike Wiebe (@mikewiebe) 76 | 77 | 78 | .. hint:: 79 | Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up. 80 | -------------------------------------------------------------------------------- /galaxy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | namespace: cisco 3 | name: dcnm 4 | version: 3.8.0-dev 5 | readme: README.md 6 | authors: 7 | - Shrishail Kariyappanavar 8 | - Mallik Mudigonda 9 | - Karthik Babu Harichandra Babu 10 | - Mike Wiebe 11 | - Praveen Ramoorthy 12 | - Allen Robel 13 | - Shangxin Du 14 | description: Ansible collection for the Cisco Nexus® Dashboard Fabric Controller (NDFC) - formerly DCNM 15 | license: Apache-2.0 16 | tags: [cisco, ndfc, dcnm, nxos, networking, vxlan] 17 | dependencies: 18 | "ansible.netcommon": ">=2.6.1" 19 | repository: https://github.com/CiscoDevNet/ansible-dcnm 20 | -------------------------------------------------------------------------------- /meta/runtime.yml: -------------------------------------------------------------------------------- 1 | # This file is used to redirect to a default action plugin if needed. 2 | # The example below demonstrates how running the dcnm_inventory module 3 | # will redirect to a common action plugin called cisco.dcnm.dcnm 4 | # 5 | #--- 6 | requires_ansible: ">=2.15.0" 7 | #plugin_routing: 8 | # action: 9 | # dcnm_inventory: 10 | # redirect: cisco.dcnm.dcnm 11 | -------------------------------------------------------------------------------- /playbooks/roles/dcnm_bootflash/create_files.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - gather_facts: false 3 | hosts: 4 | - switch1 5 | tasks: 6 | - name: Load nxos_vars 7 | ansible.builtin.include_vars: nxos_vars.yaml 8 | - name: SETUP - Create files on {{ switch1 }} 9 | cisco.nxos.nxos_command: 10 | commands: 11 | - echo 1 > bootflash:/{{ nxos_vars.switch1_file1 }} 12 | - echo 1 > bootflash:/{{ nxos_vars.switch1_file2 }} 13 | - echo 1 > bootflash:/{{ nxos_vars.switch1_file3 }} 14 | - echo 1 > bootflash:/{{ nxos_vars.switch1_file4 }} 15 | 16 | - gather_facts: false 17 | hosts: 18 | - switch2 19 | tasks: 20 | - name: Load nxos_vars 21 | ansible.builtin.include_vars: nxos_vars.yaml 22 | - name: SETUP - Create files on {{ switch2 }} 23 | cisco.nxos.nxos_command: 24 | commands: 25 | - echo 1 > bootflash:/{{ nxos_vars.switch2_file1 }} 26 | - echo 1 > bootflash:/{{ nxos_vars.switch2_file2 }} 27 | - echo 1 > bootflash:/{{ nxos_vars.switch2_file3 }} 28 | - echo 1 > bootflash:/{{ nxos_vars.switch2_file4 }} 29 | -------------------------------------------------------------------------------- /playbooks/roles/dcnm_bootflash/dcnm_hosts.yaml: -------------------------------------------------------------------------------- 1 | all: 2 | vars: 3 | ansible_user: "admin" 4 | ansible_password: "password-secret" 5 | ansible_python_interpreter: python 6 | ansible_httpapi_validate_certs: False 7 | ansible_httpapi_use_ssl: True 8 | children: 9 | dcnm: 10 | vars: 11 | ansible_connection: ansible.netcommon.httpapi 12 | ansible_network_os: cisco.dcnm.dcnm 13 | hosts: 14 | dcnm-instance.example.com 15 | nxos: 16 | vars: 17 | ansible_connection: ansible.netcommon.network_cli 18 | ansible_network_os: cisco.nxos.nxos 19 | ansible_become: true 20 | ansible_become_method: enable 21 | children: 22 | switch1: 23 | hosts: 24 | 192.168.1.1 25 | switch2: 26 | hosts: 27 | 192.168.1.2 28 | -------------------------------------------------------------------------------- /playbooks/roles/dcnm_bootflash/dcnm_tests.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # This playbook can be used to execute integration tests for 3 | # the role located in: 4 | # 5 | # tests/integration/targets/dcnm_bootflash 6 | # 7 | # Modify the hosts and vars sections with details for your testing 8 | # setup and uncomment the testcase you want to run. 9 | # 10 | - hosts: dcnm 11 | gather_facts: no 12 | connection: ansible.netcommon.httpapi 13 | 14 | vars: 15 | # testcase: dcnm_bootflash_deleted_specific 16 | # testcase: dcnm_bootflash_deleted_wildcard 17 | # testcase: dcnm_bootflash_query_specific 18 | # testcase: dcnm_bootflash_query_wildcard 19 | switch_username: admin 20 | switch_password: "password-secret" 21 | switch1: 192.168.1.2 22 | switch2: 192.168.1.3 23 | # The vars below are included in the role's defaults/main.yaml 24 | # If it is desired to override the defaults, uncomment and 25 | # modify these. 26 | # switch1_file1: air.ndfc_ut 27 | # switch1_file2: earth.ndfc_ut 28 | # switch1_file3: fire.ndfc_ut 29 | # switch1_file4: water.ndfc_ut 30 | # switch2_file1: black.ndfc_ut 31 | # switch2_file2: blue.ndfc_ut 32 | # switch2_file3: green.ndfc_ut 33 | # switch2_file4: red.ndfc_ut 34 | # wildcard_filepath: "*:/*.ndfc_ut" 35 | 36 | roles: 37 | - dcnm_bootflash 38 | -------------------------------------------------------------------------------- /playbooks/roles/dcnm_bootflash/nxos_vars.yaml: -------------------------------------------------------------------------------- 1 | nxos_vars: 2 | switch1_file1: air.ndfc_ut 3 | switch1_file2: earth.ndfc_ut 4 | switch1_file3: fire.ndfc_ut 5 | switch1_file4: water.ndfc_ut 6 | switch2_file1: black.ndfc_ut 7 | switch2_file2: blue.ndfc_ut 8 | switch2_file3: green.ndfc_ut 9 | switch2_file4: red.ndfc_ut 10 | -------------------------------------------------------------------------------- /playbooks/roles/dcnm_fabric/dcnm_hosts.yaml: -------------------------------------------------------------------------------- 1 | all: 2 | vars: 3 | ansible_user: "admin" 4 | ansible_password: "password-secret" 5 | ansible_python_interpreter: python 6 | ansible_httpapi_validate_certs: False 7 | ansible_httpapi_use_ssl: True 8 | children: 9 | dcnm: 10 | vars: 11 | ansible_connection: ansible.netcommon.httpapi 12 | ansible_network_os: cisco.dcnm.dcnm 13 | hosts: 14 | dcnm-instance.example.com: 15 | nxos: 16 | hosts: 17 | n9k-hosta.example.com: 18 | ansible_connection: ansible.netcommon.network_cli 19 | ansible_network_os: cisco.nxos.nxos 20 | ansible_ssh_port: 22 21 | -------------------------------------------------------------------------------- /playbooks/roles/dcnm_fabric/dcnm_tests.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # This playbook can be used to execute integration tests for 3 | # the roles located in: 4 | # 5 | # ./tests/integration/targets/dcnm_fabric/tests/*.yaml 6 | # 7 | # Modify the vars section with details for your testing setup. 8 | # 9 | # NOTES: 10 | # 1. For the IPFM test cases (dcnm_*_ipfm), ensure that the controller 11 | # is running in IPFM mode. i.e. Ensure that 12 | # Fabric Controller -> Admin -> System Settings -> Feature Management 13 | # "IP Fabric for Media" is checked. 14 | # 2. For all other test cases, ensure that 15 | # Fabric Controller -> Admin -> System Settings -> Feature Management 16 | # "Fabric Builder" is checked. 17 | - hosts: dcnm 18 | gather_facts: no 19 | connection: ansible.netcommon.httpapi 20 | 21 | vars: 22 | # Uncomment ONE of the following testcases 23 | # testcase: dcnm_fabric_deleted_basic 24 | # testcase: dcnm_fabric_deleted_basic_ipfm 25 | # testcase: dcnm_fabric_deleted_basic_isn 26 | # testcase: dcnm_fabric_deleted_basic_lan_classic 27 | # testcase: dcnm_fabric_deleted_basic_msd 28 | # testcase: dcnm_fabric_deleted_basic_vxlan 29 | # testcase: dcnm_fabric_merged_basic 30 | # testcase: dcnm_fabric_merged_basic_ipfm 31 | # testcase: dcnm_fabric_merged_basic_isn 32 | # testcase: dcnm_fabric_merged_save_deploy 33 | # testcase: dcnm_fabric_merged_save_deploy_ipfm 34 | # testcase: dcnm_fabric_replaced_basic 35 | # testcase: dcnm_fabric_replaced_basic_ipfm 36 | # testcase: dcnm_fabric_replaced_basic_isn 37 | # testcase: dcnm_fabric_replaced_basic_vxlan 38 | # testcase: dcnm_fabric_replaced_basic_vxlan_site_id 39 | # testcase: dcnm_fabric_replaced_save_deploy 40 | # testcase: dcnm_fabric_replaced_save_deploy_ipfm 41 | # testcase: dcnm_fabric_query_basic.yaml 42 | fabric_name_1: VXLAN_EVPN_Fabric 43 | fabric_type_1: VXLAN_EVPN 44 | fabric_name_2: VXLAN_EVPN_MSD_Fabric 45 | fabric_type_2: VXLAN_EVPN_MSD 46 | fabric_name_3: LAN_CLASSIC_Fabric 47 | fabric_type_3: LAN_CLASSIC 48 | fabric_name_4: IPFM_Fabric 49 | fabric_type_4: IPFM 50 | fabric_name_5: ISN_Fabric 51 | fabric_type_5: ISN 52 | leaf_1: 172.22.150.103 53 | leaf_2: 172.22.150.104 54 | nxos_username: admin 55 | nxos_password: myNxosPassword 56 | 57 | roles: 58 | - dcnm_fabric 59 | -------------------------------------------------------------------------------- /playbooks/roles/dcnm_image_policy/dcnm_hosts.yaml: -------------------------------------------------------------------------------- 1 | all: 2 | vars: 3 | ansible_user: "admin" 4 | ansible_password: "password-secret" 5 | ansible_python_interpreter: python 6 | ansible_httpapi_validate_certs: False 7 | ansible_httpapi_use_ssl: True 8 | children: 9 | dcnm: 10 | vars: 11 | ansible_connection: ansible.netcommon.httpapi 12 | ansible_network_os: cisco.dcnm.dcnm 13 | hosts: 14 | dcnm-instance.example.com: 15 | nxos: 16 | hosts: 17 | n9k-hosta.example.com: 18 | ansible_connection: ansible.netcommon.network_cli 19 | ansible_network_os: cisco.nxos.nxos 20 | ansible_ssh_port: 22 21 | -------------------------------------------------------------------------------- /playbooks/roles/dcnm_image_policy/dcnm_tests.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # This playbook can be used to execute integration tests for 3 | # the role located in: 4 | # 5 | # tests/integration/targets/dcnm_image_policy 6 | # 7 | # Modify the hosts and vars sections with details for your testing 8 | # setup and uncomment the testcase you want to run. 9 | # 10 | - hosts: dcnm 11 | gather_facts: no 12 | connection: ansible.netcommon.httpapi 13 | 14 | vars: 15 | # testcase: dcnm_image_policy_deleted 16 | # testcase: dcnm_image_policy_merged 17 | # testcase: dcnm_image_policy_overridden 18 | # testcase: dcnm_image_policy_query 19 | # testcase: dcnm_image_policy_replaced 20 | switch_username: admin 21 | switch_password: "foobar" 22 | spine1: 192.168.1.2 23 | spine2: 192.168.1.3 24 | leaf1: 192.168.1.4 25 | leaf2: 192.168.1.5 26 | leaf3: 192.168.1.6 27 | leaf4: 192.168.1.7 28 | install_package_1: cfg_cmp-0.3.1.0-1.x86_64.rpm 29 | uninstall_package_1: mtx-grpctunnel-2.1.0.0-10.4.1.lib32_64_n9000 30 | image_policy_1: "KR5M" 31 | image_policy_2: "NR3F" 32 | epld_image_1: n9000-epld.10.2.5.M.img 33 | epld_image_2: n9000-epld.10.3.1.F.img 34 | nxos_image_1: n9000-dk9.10.2.5.M.bin 35 | nxos_image_2: n9000-dk9.10.3.1.F.bin 36 | nxos_release_1: 10.2.5_nxos64-cs_64bit 37 | nxos_release_2: 10.3.1_nxos64-cs_64bit 38 | 39 | roles: 40 | - dcnm_image_policy 41 | -------------------------------------------------------------------------------- /playbooks/roles/dcnm_image_upgrade/dcnm_hosts.yaml: -------------------------------------------------------------------------------- 1 | all: 2 | vars: 3 | ansible_user: "admin" 4 | ansible_password: "password-ndfc" 5 | switch_password: "password-switch" 6 | ansible_python_interpreter: python 7 | ansible_httpapi_validate_certs: False 8 | ansible_httpapi_use_ssl: True 9 | children: 10 | ndfc: 11 | vars: 12 | ansible_connection: ansible.netcommon.httpapi 13 | ansible_network_os: cisco.dcnm.dcnm 14 | hosts: 15 | 192.168.1.1: 16 | -------------------------------------------------------------------------------- /playbooks/roles/dcnm_image_upgrade/dcnm_tests.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # This playbook can be used to execute integration tests for 3 | # the role located in: 4 | # 5 | # tests/integration/targets/dcnm_image_upgrade 6 | # 7 | # Modify the hosts and vars sections with details for your testing 8 | # setup and uncomment the testcase you want to run. 9 | # 10 | - hosts: dcnm 11 | gather_facts: no 12 | connection: ansible.netcommon.httpapi 13 | 14 | vars: 15 | # testcase: 00_setup_create_fabric 16 | # testcase: 01_setup_add_switches_to_fabric 17 | # testcase: 02_setup_replace_image_policies 18 | # testcase: deleted 19 | # testcase: deleted_1x_switch 20 | # testcase: merged_global_config 21 | # testcase: merged_override_global_config 22 | # testcase: query 23 | fabric_name: LAN_Classic_Fabric 24 | switch_username: admin 25 | switch_password: "{{ switch_password }}" 26 | leaf1: 192.168.1.2 27 | leaf2: 192.168.1.3 28 | spine1: 192.168.1.4 29 | # for dcnm_image_policy and dcnm_image_upgrade roles 30 | image_policy_1: NR1F 31 | image_policy_2: NR2F 32 | # for dcnm_image_policy role 33 | epld_image_1: n9000-epld.10.3.1.F.img 34 | epld_image_2: n9000-epld.10.3.1.F.img 35 | nxos_image_1: nxos64-cs.10.3.1.F.bin 36 | nxos_image_2: nxos64-cs.10.3.2.F.bin 37 | nxos_release_1: 10.3.1_nxos64-cs_64bit 38 | nxos_release_2: 10.3.2_nxos64-cs_64bit 39 | # for dcnm_image_upgrade role 40 | fabric_name_1: "{{ fabric_name }}" 41 | ansible_switch_1: "{{ leaf1 }}" 42 | ansible_switch_2: "{{ leaf2 }}" 43 | ansible_switch_3: "{{ spine1 }}" 44 | 45 | roles: 46 | - dcnm_image_upgrade 47 | -------------------------------------------------------------------------------- /playbooks/roles/dcnm_interface/dcnm_hosts.yaml: -------------------------------------------------------------------------------- 1 | all: 2 | vars: 3 | ansible_user: "admin" 4 | ansible_password: "password" 5 | ansible_python_interpreter: python 6 | ansible_httpapi_validate_certs: False 7 | ansible_httpapi_use_ssl: True 8 | children: 9 | ndfc: 10 | vars: 11 | ansible_connection: ansible.netcommon.httpapi 12 | ansible_network_os: cisco.dcnm.dcnm 13 | hosts: 14 | nac-ndfc1: 15 | ansible_host: 10.0.55.128 -------------------------------------------------------------------------------- /playbooks/roles/dcnm_interface/dcnm_tests.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # This playbook can be used to execute integration tests for 3 | # the role located in: 4 | # 5 | # tests/integration/targets/dcnm_interface 6 | # 7 | # Modify the vars section with details for your testing setup. 8 | # 9 | - hosts: ndfc 10 | gather_facts: no 11 | connection: ansible.netcommon.httpapi 12 | 13 | vars: 14 | # Uncomment testcase to run a specific test 15 | testcase: dcnm_vpc* 16 | ansible_it_fabric: test_fabric 17 | ansible_switch1: 192.168.1.13 18 | ansible_switch2: 192.168.1.14 19 | ansible_eth_intf2: Ethernet1/2 20 | ansible_eth_intf3: Ethernet1/3 21 | ansible_eth_intf4: Ethernet1/4 22 | ansible_eth_intf5: Ethernet1/5 23 | ansible_eth_intf6: Ethernet1/6 24 | ansible_eth_intf7: Ethernet1/7 25 | ansible_eth_intf8: Ethernet1/8 26 | ansible_eth_intf9: Ethernet1/9 27 | ansible_eth_intf10: Ethernet1/10 28 | ansible_eth_intf11: Ethernet1/11 29 | ansible_eth_intf12: Ethernet1/12 30 | ansible_eth_intf13: Ethernet1/13 31 | ansible_eth_intf14: Ethernet1/14 32 | ansible_eth_intf15: Ethernet1/15 33 | ansible_eth_intf16: Ethernet1/16 34 | ansible_eth_intf17: Ethernet1/17 35 | ansible_eth_intf18: Ethernet1/18 36 | ansible_eth_intf19: Ethernet1/19 37 | ansible_eth_intf20: Ethernet1/20 38 | ansible_eth_intf21: Ethernet1/21 39 | ansible_eth_intf22: Ethernet1/22 40 | ansible_eth_intf23: Ethernet1/23 41 | ansible_eth_intf24: Ethernet1/24 42 | 43 | roles: 44 | - dcnm_interface -------------------------------------------------------------------------------- /playbooks/roles/dcnm_maintenance_mode/dcnm_hosts.yaml: -------------------------------------------------------------------------------- 1 | all: 2 | vars: 3 | ansible_user: "admin" 4 | ansible_password: "password-secret" 5 | ansible_python_interpreter: python 6 | ansible_httpapi_validate_certs: False 7 | ansible_httpapi_use_ssl: True 8 | children: 9 | dcnm: 10 | vars: 11 | ansible_connection: ansible.netcommon.httpapi 12 | ansible_network_os: cisco.dcnm.dcnm 13 | hosts: 14 | dcnm-instance.example.com: 15 | nxos: 16 | hosts: 17 | n9k-hosta.example.com: 18 | ansible_connection: ansible.netcommon.network_cli 19 | ansible_network_os: cisco.nxos.nxos 20 | ansible_ssh_port: 22 21 | -------------------------------------------------------------------------------- /playbooks/roles/dcnm_maintenance_mode/dcnm_tests.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # This playbook can be used to execute integration tests for 3 | # the role located in: 4 | # 5 | # tests/integration/targets/dcnm_maintenance_mode 6 | # 7 | # Modify the vars section with details for your testing setup. 8 | # 9 | # NOTES: 10 | # 1. For the IPFM test cases (dcnm_*_ipfm), ensure that the controller 11 | # is running in IPFM mode. i.e. Ensure that 12 | # Fabric Controller -> Admin -> System Settings -> Feature Management 13 | # "IP Fabric for Media" is checked. 14 | # 2. For all other test cases, ensure that 15 | # Fabric Controller -> Admin -> System Settings -> Feature Management 16 | # "Fabric Builder" is checked. 17 | - hosts: dcnm 18 | gather_facts: no 19 | connection: ansible.netcommon.httpapi 20 | 21 | vars: 22 | # See the following location for available test cases: 23 | # tests/integration/targets/dcnm_maintenance_mode/tests 24 | # testcase: 00_setup_fabrics_1x_rw 25 | # testcase: 00_setup_fabrics_2x_rw 26 | # testcase: 01_merged_maintenance_mode_deploy 27 | # testcase: 01_merged_maintenance_mode_no_deploy 28 | fabric_name_1: VXLAN_EVPN_Fabric 29 | fabric_type_1: VXLAN_EVPN 30 | fabric_name_2: VXLAN_EVPN_MSD_Fabric 31 | fabric_type_2: VXLAN_EVPN_MSD 32 | fabric_name_3: LAN_CLASSIC_Fabric 33 | fabric_type_3: LAN_CLASSIC 34 | fabric_name_4: IPFM_Fabric 35 | fabric_type_4: IPFM 36 | leaf_1: 172.22.150.103 37 | leaf_2: 172.22.150.104 38 | nxos_username: admin 39 | nxos_password: myNxosPassword 40 | 41 | roles: 42 | - dcnm_maintenance_mode 43 | -------------------------------------------------------------------------------- /playbooks/roles/dcnm_network/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | # This ansible.cfg file is only used for testing purposes in this directory. 3 | roles_path = /collections/ansible_collections/cisco/dcnm/tests/integration/targets -------------------------------------------------------------------------------- /playbooks/roles/dcnm_network/dcnm_hosts.yaml: -------------------------------------------------------------------------------- 1 | all: 2 | vars: 3 | ansible_user: "admin" 4 | ansible_password: "password-secret" 5 | ansible_python_interpreter: python 6 | ansible_httpapi_validate_certs: False 7 | ansible_httpapi_use_ssl: True 8 | children: 9 | dcnm: 10 | vars: 11 | ansible_connection: ansible.netcommon.httpapi 12 | ansible_network_os: cisco.dcnm.dcnm 13 | hosts: 14 | nac-ndfc1: 15 | ansible_host: 10.10.5.1 -------------------------------------------------------------------------------- /playbooks/roles/dcnm_network/dcnm_tests.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # This playbook can be used to execute integration tests for 3 | # the role located in: 4 | # 5 | # tests/integration/targets/dcnm_network 6 | # 7 | # Modify the vars section with details for your testing setup. 8 | # 9 | # NOTES: 10 | # 1. Ensure that the switches defined by ansible_switch1 and ansible_switch2 are 11 | # not vPC Pairs. 12 | - hosts: dcnm 13 | gather_facts: no 14 | connection: ansible.netcommon.httpapi 15 | 16 | vars: 17 | # Uncomment testcase to run a specific test 18 | # testcase: replaced_net_all 19 | test_fabric: nac-ndfc1 20 | ansible_switch1: 192.168.1.1 21 | ansible_switch2: 192.168.1.2 22 | ansible_sw1_int1: Ethernet1/15 23 | ansible_sw1_int2: Ethernet1/16 24 | ansible_sw1_int3: Ethernet1/17 25 | ansible_sw1_int4: Ethernet1/18 26 | #--- 27 | ansible_sw2_int1: Ethernet1/15 28 | ansible_sw2_int2: Ethernet1/16 29 | ansible_sw2_int3: Ethernet1/17 30 | ansible_sw2_int4: Ethernet1/18 31 | ansible_sw2_int5: Ethernet1/19 32 | ansible_sw2_int6: Ethernet1/20 33 | 34 | roles: 35 | - dcnm_network 36 | -------------------------------------------------------------------------------- /playbooks/roles/dcnm_policy/dcnm_hosts.yaml: -------------------------------------------------------------------------------- 1 | all: 2 | vars: 3 | ansible_user: "admin" 4 | ansible_password: "password" 5 | ansible_python_interpreter: python 6 | ansible_httpapi_validate_certs: False 7 | ansible_httpapi_use_ssl: True 8 | children: 9 | dcnm: 10 | vars: 11 | ansible_connection: ansible.netcommon.httpapi 12 | ansible_network_os: cisco.dcnm.dcnm 13 | hosts: 14 | nac-ndfc1: 15 | ansible_host: 10.15.0.5 -------------------------------------------------------------------------------- /playbooks/roles/dcnm_policy/dcnm_tests.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # This playbook can be used to execute integration tests for 3 | # the role located in: 4 | # 5 | # tests/integration/targets/dcnm_policy 6 | # 7 | # Modify the vars section with details for your testing setup. 8 | # 9 | - hosts: dcnm 10 | gather_facts: no 11 | connection: ansible.netcommon.httpapi 12 | 13 | vars: 14 | # Uncomment 'testcase:' to run a specific test under 'tests/integration/targets/dcnm_policy/tests/dcnm' 15 | # testcase: dcnm_policy_with* 16 | ansible_it_fabric: test_fabric 17 | ansible_switch1: 192.168.55.21 18 | ansible_sw1_sno: 9YEXD0OHA7Z 19 | ansible_switch2: 192.168.55.22 20 | ansible_sw2_sno: 9M2TXMZ7D3N 21 | 22 | roles: 23 | - dcnm_policy 24 | -------------------------------------------------------------------------------- /playbooks/roles/dcnm_vrf/dcnm_hosts.yaml: -------------------------------------------------------------------------------- 1 | all: 2 | vars: 3 | ansible_user: "admin" 4 | ansible_password: "password-ndfc" 5 | switch_password: "password-switch" 6 | ansible_python_interpreter: python 7 | ansible_httpapi_validate_certs: False 8 | ansible_httpapi_use_ssl: True 9 | children: 10 | ndfc: 11 | vars: 12 | ansible_connection: ansible.netcommon.httpapi 13 | ansible_network_os: cisco.dcnm.dcnm 14 | hosts: 15 | 192.168.1.1: 16 | -------------------------------------------------------------------------------- /playbooks/roles/dcnm_vrf/dcnm_tests.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # This playbook can be used to execute integration tests for 3 | # the roles located in: 4 | # 5 | # REPO_ROOT/tests/integration/targets/dcnm_vrf/tests/dcnm/*.yaml 6 | # 7 | # Either: 8 | # 9 | # 1. Modify the following: 10 | # 11 | # - The vars section below with details for your testing setup. 12 | # - dcnm_hosts.yaml in this directory 13 | # 14 | # 2. Run the tests 15 | # 16 | # ansible-playbook dcnm_tests.yaml -i dcnm_hosts.yaml 17 | # 18 | # OR: 19 | # 20 | # 1. Modify ../../files/dynamic_inventory.py to align with your setup 21 | # 22 | # This must contain the vars mentioned below and controller 23 | # info from dcnm_hosts.yaml (modified for your setup) 24 | # 25 | # 2. Run the tests 26 | # 27 | # ansible-playbook dcnm_tests.yaml -i ../../files/dynamic_inventory.py 28 | # 29 | # 30 | - hosts: dcnm 31 | gather_facts: no 32 | connection: ansible.netcommon.httpapi 33 | # Uncomment and modify if not using dynamic_inventory.py 34 | # See the individual test yaml files for a description of 35 | # how each var below is used in each test. Some tests, 36 | # for example, do not use interface_1. 37 | # vars: 38 | # fabric_1: f1 39 | # switch_1: 10.1.1.2 40 | # switch_2: 10.1.1.3 41 | # switch_3: 10.1.1.4 42 | # interface_1: Ethernet1/1 43 | # interface_2: Ethernet1/2 44 | # interface_3: Ethernet1/3 45 | ## Uncomment ONE of the following testcases 46 | # testcase: deleted 47 | # testcase: merged 48 | # testcase: query 49 | 50 | roles: 51 | - dcnm_vrf 52 | -------------------------------------------------------------------------------- /playbooks/roles/ndfc_interface/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | # This ansible.cfg file is only used for testing purposes in this directory. 3 | roles_path = /collections/ansible_collections/cisco/dcnm/tests/integration/targets -------------------------------------------------------------------------------- /playbooks/roles/ndfc_interface/ndfc_hosts.yaml: -------------------------------------------------------------------------------- 1 | all: 2 | vars: 3 | ansible_user: "admin" 4 | ansible_password: "password" 5 | ansible_python_interpreter: python 6 | ansible_httpapi_validate_certs: False 7 | ansible_httpapi_use_ssl: True 8 | children: 9 | ndfc: 10 | vars: 11 | ansible_connection: ansible.netcommon.httpapi 12 | ansible_network_os: cisco.dcnm.dcnm 13 | hosts: 14 | nac-ndfc1: 15 | ansible_host: 10.0.55.128 16 | -------------------------------------------------------------------------------- /playbooks/roles/ndfc_interface/ndfc_tests.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # This playbook can be used to execute integration tests for 3 | # the role located in: 4 | # 5 | # tests/integration/targets/dcnm_interface 6 | # 7 | # Modify the vars section with details for your testing setup. 8 | # 9 | - hosts: ndfc 10 | gather_facts: no 11 | connection: ansible.netcommon.httpapi 12 | 13 | vars: 14 | # Uncomment testcase to run a specific test 15 | testcase: ndfc_pc_members 16 | ansible_it_fabric: test_fabric 17 | ansible_switch1: 192.168.1.13 18 | ansible_switch2: 192.168.1.14 19 | ansible_eth_intf2: Ethernet1/2 20 | ansible_eth_intf3: Ethernet1/3 21 | ansible_eth_intf4: Ethernet1/4 22 | ansible_eth_intf5: Ethernet1/5 23 | ansible_eth_intf6: Ethernet1/6 24 | ansible_eth_intf7: Ethernet1/7 25 | ansible_eth_intf8: Ethernet1/8 26 | ansible_eth_intf9: Ethernet1/9 27 | ansible_eth_intf10: Ethernet1/10 28 | ansible_eth_intf11: Ethernet1/11 29 | ansible_eth_intf12: Ethernet1/12 30 | ansible_eth_intf13: Ethernet1/13 31 | ansible_eth_intf14: Ethernet1/14 32 | ansible_eth_intf15: Ethernet1/15 33 | ansible_eth_intf16: Ethernet1/16 34 | ansible_eth_intf17: Ethernet1/17 35 | ansible_eth_intf18: Ethernet1/18 36 | ansible_eth_intf19: Ethernet1/19 37 | ansible_eth_intf20: Ethernet1/20 38 | ansible_eth_intf21: Ethernet1/21 39 | port_channel_1: port-channel801 40 | port_channel_2: port-channel802 41 | port_channel_3: port-channel803 42 | 43 | roles: 44 | - ndfc_interface 45 | -------------------------------------------------------------------------------- /plugins/README.md: -------------------------------------------------------------------------------- 1 | # Collections Plugins Directory 2 | 3 | This directory can be used to ship various plugins inside an Ansible collection. Each plugin is placed in a folder that 4 | is named after the type of plugin it is in. It can also include the `module_utils` and `modules` directory that 5 | would contain module utils and modules respectively. 6 | 7 | Here is an example directory of the majority of plugins currently supported by Ansible: 8 | 9 | ``` 10 | └── plugins 11 | ├── action 12 | ├── become 13 | ├── cache 14 | ├── callback 15 | ├── cliconf 16 | ├── connection 17 | ├── filter 18 | ├── httpapi 19 | ├── inventory 20 | ├── lookup 21 | ├── module_utils 22 | ├── modules 23 | ├── netconf 24 | ├── shell 25 | ├── strategy 26 | ├── terminal 27 | ├── test 28 | └── vars 29 | ``` 30 | 31 | A full list of plugin types can be found at [Working With Plugins](https://docs.ansible.com/ansible/devel/plugins/plugins.html). -------------------------------------------------------------------------------- /plugins/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/__init__.py -------------------------------------------------------------------------------- /plugins/action/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/action/__init__.py -------------------------------------------------------------------------------- /plugins/action/dcnm_vrf.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020-2022 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | 19 | from ansible_collections.ansible.netcommon.plugins.action.network import ( 20 | ActionModule as ActionNetworkModule, 21 | ) 22 | from ansible.utils.display import Display 23 | 24 | display = Display() 25 | 26 | 27 | class ActionModule(ActionNetworkModule): 28 | def run(self, tmp=None, task_vars=None): 29 | 30 | if ( 31 | self._task.args.get("state") == "merged" 32 | or self._task.args.get("state") == "overridden" 33 | or self._task.args.get("state") == "replaced" 34 | ): 35 | for con in self._task.args["config"]: 36 | if "attach" in con: 37 | for at in con["attach"]: 38 | if "vlan_id" in at: 39 | msg = "Playbook parameter vlan_id should not be specified under the attach: block. Please specify this under the config: block instead" # noqa 40 | return {"failed": True, "msg": msg} 41 | if "vrf_lite" in at: 42 | try: 43 | for vl in at["vrf_lite"]: 44 | continue 45 | except TypeError: 46 | msg = "Please specify interface parameter under vrf_lite section in the playbook" 47 | return {"failed": True, "msg": msg} 48 | 49 | self.result = super(ActionModule, self).run(task_vars=task_vars) 50 | return self.result 51 | -------------------------------------------------------------------------------- /plugins/httpapi/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/httpapi/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/bootflash/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/bootflash/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/api.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..conversion import ConversionUtils 23 | 24 | 25 | class Api: 26 | """ 27 | ## API endpoints - Api() 28 | 29 | ### Description 30 | Common methods and properties for Api() subclasses. 31 | 32 | ### Path 33 | ``/appcenter/cisco/ndfc/api`` 34 | """ 35 | 36 | def __init__(self): 37 | self.class_name = self.__class__.__name__ 38 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 39 | self.conversion = ConversionUtils() 40 | # Popuate in subclasses to indicate which properties 41 | # are mandatory for the subclass. 42 | self.required_properties = set() 43 | self.log.debug("ENTERED api.Api()") 44 | self.api = "/appcenter/cisco/ndfc/api" 45 | self._init_properties() 46 | 47 | def _init_properties(self): 48 | self.properties = {} 49 | self.properties["path"] = None 50 | self.properties["verb"] = None 51 | 52 | @property 53 | def path(self): 54 | """ 55 | Return the endpoint path. 56 | """ 57 | return self.properties["path"] 58 | 59 | @property 60 | def verb(self): 61 | """ 62 | Return the endpoint verb. 63 | """ 64 | return self.properties["verb"] 65 | -------------------------------------------------------------------------------- /plugins/module_utils/common/api/api_nd.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..conversion import ConversionUtils 23 | 24 | 25 | class ApiNd: 26 | """ 27 | ## API endpoints for ND- ApiNd() 28 | 29 | ### Description 30 | Common methods and properties for ApiNd() subclasses. 31 | 32 | ### Path 33 | ``/api`` 34 | """ 35 | 36 | def __init__(self): 37 | self.class_name = self.__class__.__name__ 38 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 39 | self.conversion = ConversionUtils() 40 | # Popuate in subclasses to indicate which properties 41 | # are mandatory for the subclass. 42 | self.required_properties = set() 43 | self.log.debug("ENTERED api.ApiNd()") 44 | self.api = "/api" 45 | self._init_properties() 46 | 47 | def _init_properties(self): 48 | self._path = None 49 | self._verb = None 50 | 51 | @property 52 | def path(self): 53 | """ 54 | Return the endpoint path. 55 | """ 56 | return self._path 57 | 58 | @property 59 | def verb(self): 60 | """ 61 | Return the endpoint verb. 62 | """ 63 | return self._verb 64 | -------------------------------------------------------------------------------- /plugins/module_utils/common/api/config/class_ep/class_ep.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..config import Config 23 | 24 | 25 | class ClassEp(Config): 26 | """ 27 | ## API endpoints - Api().Config().ClassEp() 28 | 29 | ### Description 30 | Common methods and properties for Api().Config().Class() subclasses. 31 | 32 | ### Path 33 | ``/api/config/class`` 34 | 35 | ### Notes 36 | 1. We could not use Class() as the class name since it's a 37 | reserved Python name. 38 | 2. Same goes for the directory name (class_ep vs class). 39 | i.e. imports didn't work when we tried class as a directory name 40 | or a file name. 41 | """ 42 | 43 | def __init__(self): 44 | super().__init__() 45 | self.class_name = self.__class__.__name__ 46 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 47 | self.log.debug("ENTERED api.config.class_ep.ClassEp()") 48 | self.class_ep = f"{self.config}/class" 49 | -------------------------------------------------------------------------------- /plugins/module_utils/common/api/config/class_ep/v2/sites/sites.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..v2 import V2 23 | 24 | 25 | class EpSites(V2): 26 | """ 27 | ## Api().Config().ClassEp().V2().EpSites() 28 | 29 | ### Description 30 | 31 | Endpoint information for retrieving Federation Sites from the 32 | controller. 33 | 34 | ### Raises 35 | 36 | - None 37 | 38 | ### Path 39 | 40 | ``/api/config/class/v2/sites`` 41 | 42 | ### Verb 43 | 44 | ``GET`` 45 | 46 | ### Parameters 47 | 48 | - path: retrieve the path for the endpoint 49 | - verb: retrieve the verb for the endpoint 50 | 51 | ### Usage 52 | 53 | ```python 54 | from ansible_collections.cisco.dcnm.plugins.module_utils.common.api.config.class_ep.v2.sites import EpSites 55 | instance = EpSites() 56 | path = instance.path 57 | verb = instance.verb 58 | ``` 59 | 60 | """ 61 | 62 | def __init__(self): 63 | super().__init__() 64 | self.class_name = self.__class__.__name__ 65 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 66 | self.log.debug("ENTERED api.config.class_ep.v2.sites.EpSites()") 67 | # trailing backslash is needed here 68 | self._path = f"{self.v2}/sites/" 69 | self._verb = "GET" 70 | -------------------------------------------------------------------------------- /plugins/module_utils/common/api/config/class_ep/v2/v2.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..class_ep import ClassEp 23 | 24 | 25 | class V2(ClassEp): 26 | """ 27 | ## API endpoints - Api().Config().ClassEp().V2() 28 | 29 | ### Description 30 | Common methods and properties for Api().Config().ClassEp().V2() subclasses. 31 | 32 | ### Path 33 | ``/api/config/class/v2`` 34 | """ 35 | 36 | def __init__(self): 37 | super().__init__() 38 | self.class_name = self.__class__.__name__ 39 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 40 | self.log.debug("ENTERED api.config.class_ep.v2.V2()") 41 | self.v2 = f"{self.class_ep}/v2" 42 | -------------------------------------------------------------------------------- /plugins/module_utils/common/api/config/config.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..api_nd import ApiNd 23 | 24 | 25 | class Config(ApiNd): 26 | """ 27 | ## config API enpoints - Api().Config() 28 | 29 | ### Description 30 | Common methods and properties for API config subclasses. 31 | 32 | ### Path 33 | ``/api/config/`` 34 | """ 35 | 36 | def __init__(self): 37 | super().__init__() 38 | self.class_name = self.__class__.__name__ 39 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 40 | self.log.debug("ENTERED api.config.Config()") 41 | self.config = f"{self.api}/config" 42 | -------------------------------------------------------------------------------- /plugins/module_utils/common/api/config/federation/federation.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..config import Config 23 | 24 | 25 | class Federation(Config): 26 | """ 27 | ## Federation API enpoints - Api().Config().Federation() 28 | 29 | ### Description 30 | Common methods and properties for API Federation subclasses. 31 | 32 | ### Path 33 | ``/api/config/federation/`` 34 | """ 35 | 36 | def __init__(self): 37 | super().__init__() 38 | self.class_name = self.__class__.__name__ 39 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 40 | self.log.debug("ENTERED api.config.Federation()") 41 | self.federation = f"{self.config}/federation" 42 | 43 | 44 | class EpFederationMembers(Federation): 45 | def __init__(self): 46 | super().__init__() 47 | self.class_name = self.__class__.__name__ 48 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 49 | 50 | self._verb = "GET" 51 | self._path = f"{self.federation}/members" 52 | msg = "ENTERED api.config.federation." 53 | msg += f"Federation.{self.class_name}" 54 | self.log.debug(msg) 55 | -------------------------------------------------------------------------------- /plugins/module_utils/common/api/config/federation/manager/manager.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ansible_collections.cisco.dcnm.plugins.module_utils.common.api.config.federation.federation import \ 23 | Federation 24 | 25 | 26 | class Manager(Federation): 27 | """ 28 | ## Federation Manager API enpoints - Api().Config().Federation().Manager() 29 | 30 | ### Description 31 | Common methods and properties for Federation Manager endpoint subclasses. 32 | 33 | ### Path 34 | ``/api/config/federation/manager`` 35 | """ 36 | 37 | def __init__(self): 38 | super().__init__() 39 | self.class_name = self.__class__.__name__ 40 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 41 | self.log.debug("ENTERED api.config.federation.manager.Manager()") 42 | self.manager = f"{self.federation}/manager" 43 | 44 | 45 | class EpFederationManagerGet(Manager): 46 | """ 47 | ## Get Federation Manager - Api().Config().Federation().Manager().EpFederationManagerGet() 48 | 49 | ### Description 50 | Common methods and properties for Federation Manager endpoint subclasses. 51 | 52 | ### Path 53 | ``/api/config/federation/manager`` 54 | """ 55 | def __init__(self): 56 | super().__init__() 57 | self.class_name = self.__class__.__name__ 58 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 59 | 60 | self._verb = "GET" 61 | self._path = f"{self.manager}/mo" 62 | 63 | msg = "ENTERED api.config.federation.manager." 64 | msg += f"Manager.{self.class_name}" 65 | self.log.debug(msg) 66 | -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/configtemplate/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/configtemplate/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/configtemplate/configtemplate.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..v1 import V1 23 | 24 | 25 | class ConfigTemplate(V1): 26 | """ 27 | ## V1 API - ConfigTemplate() 28 | 29 | ### Description 30 | Common methods and properties for api.v1.ConfigTemplate() subclasses 31 | 32 | ### Path 33 | ``/appcenter/cisco/ndfc/api/v1/configtemplate`` 34 | """ 35 | 36 | def __init__(self): 37 | super().__init__() 38 | self.class_name = self.__class__.__name__ 39 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 40 | self.configtemplate = f"{self.v1}/configtemplate" 41 | self.log.debug("ENTERED api.v1.configtemplate.ConfigTemplate()") 42 | -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/configtemplate/rest/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/configtemplate/rest/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/configtemplate/rest/config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/configtemplate/rest/config/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/configtemplate/rest/config/config.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # pylint: disable=line-too-long 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..rest import Rest 23 | 24 | 25 | class Config(Rest): 26 | """ 27 | ## V1 API Config() - api.v1.configtemplate.rest.config.Config() 28 | 29 | ### Description 30 | Common methods and properties for api.v1.configtemplate.rest.config.Config() subclasses. 31 | 32 | ### Path 33 | - ``/api/v1/configtemplate/rest/config`` 34 | """ 35 | 36 | def __init__(self): 37 | super().__init__() 38 | self.class_name = self.__class__.__name__ 39 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 40 | self.config = f"{self.rest}/config" 41 | msg = f"ENTERED api.v1.rest.config.{self.class_name}" 42 | self.log.debug(msg) 43 | self._build_properties() 44 | 45 | def _build_properties(self): 46 | """ 47 | - Populate class-specific properties. 48 | """ 49 | -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/configtemplate/rest/config/templates/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/configtemplate/rest/config/templates/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/configtemplate/rest/rest.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # pylint: disable=line-too-long 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..configtemplate import ConfigTemplate 23 | 24 | 25 | class Rest(ConfigTemplate): 26 | """ 27 | ## V1 API ConfigTemplate() - api.v1.configtemplate.rest.Rest() 28 | 29 | ### Description 30 | Common methods and properties for api.v1.configtemplate.rest.Rest() subclasses. 31 | 32 | ### Path 33 | - ``/api/v1/configtemplate/rest`` 34 | """ 35 | 36 | def __init__(self): 37 | super().__init__() 38 | self.class_name = self.__class__.__name__ 39 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 40 | self.rest = f"{self.configtemplate}/rest" 41 | msg = f"ENTERED api.v1.configtemplate.rest.{self.class_name}" 42 | self.log.debug(msg) 43 | self._build_properties() 44 | 45 | def _build_properties(self): 46 | """ 47 | - Populate class-specific properties. 48 | """ 49 | -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/fm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/fm/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/imagemanagement/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/imagemanagement/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/imagemanagement/imagemanagement.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..v1 import V1 23 | 24 | 25 | class ImageManagement(V1): 26 | """ 27 | ## V1 API - ImageManagement() 28 | 29 | ### Description 30 | Common methods and properties for CommonV1().ImageManagement() subclasses 31 | 32 | ### Path 33 | ``/appcenter/cisco/ndfc/api/v1/imagemanagement`` 34 | """ 35 | 36 | def __init__(self): 37 | super().__init__() 38 | self.class_name = self.__class__.__name__ 39 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 40 | self.imagemanagement = f"{self.v1}/imagemanagement" 41 | self.log.debug("ENTERED api.v1.imagemanagement.ImageManagement()") 42 | -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/imagemanagement/rest/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/imagemanagement/rest/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/imagemanagement/rest/discovery/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/imagemanagement/rest/discovery/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/imagemanagement/rest/imagemgnt/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/imagemanagement/rest/imagemgnt/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/imagemanagement/rest/imagemgnt/bootflash/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/imagemanagement/rest/imagemgnt/bootflash/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/imagemanagement/rest/imagemgnt/imagemgnt.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..rest import Rest 23 | 24 | 25 | class ImageMgnt(Rest): 26 | """ 27 | ## api.v1.imagemanagement.rest.imagemgt.ImageMgnt() 28 | 29 | ### Description 30 | Common methods and properties for ImageMgnt() subclasses 31 | 32 | ### Path 33 | ``/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/imagemgnt`` 34 | """ 35 | 36 | def __init__(self): 37 | super().__init__() 38 | self.class_name = self.__class__.__name__ 39 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 40 | self.image_mgmt = f"{self.rest}/imagemgnt" 41 | self.log.debug("ENTERED api.v1.imagemanagement.rest.imagemgnt.ImageMgnt()") 42 | -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/imagemanagement/rest/imageupgrade/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/imagemanagement/rest/imageupgrade/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/imagemanagement/rest/policymgnt/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/imagemanagement/rest/policymgnt/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/imagemanagement/rest/rest.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # pylint: disable=line-too-long 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..imagemanagement import ImageManagement 23 | 24 | 25 | class Rest(ImageManagement): 26 | """ 27 | ## api.v1.imagemanagement.rest.Rest() 28 | 29 | ### Description 30 | Common methods and properties api.v1.imagemanagement.rest subclasses. 31 | 32 | ### Path 33 | - ``/api/v1/imagemanagement/rest`` 34 | """ 35 | 36 | def __init__(self): 37 | super().__init__() 38 | self.class_name = self.__class__.__name__ 39 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 40 | self.rest = f"{self.imagemanagement}/rest" 41 | msg = f"ENTERED api.v1.imagemanagement.rest.{self.class_name}" 42 | self.log.debug(msg) 43 | self._build_properties() 44 | 45 | def _build_properties(self): 46 | """ 47 | - Populate properties specific to this class and its subclasses. 48 | """ 49 | -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/imagemanagement/rest/stagingmanagement/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/imagemanagement/rest/stagingmanagement/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/lan_fabric/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/lan_fabric/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/lan_fabric/lan_fabric.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..v1 import V1 23 | 24 | 25 | class LanFabric(V1): 26 | """ 27 | ## api.v1.lan-fabric.LanFabric() 28 | 29 | ### Description 30 | Common methods and properties for api.v1.lan-fabric.LanFabric() subclasses 31 | 32 | ### Path 33 | ``/appcenter/cisco/ndfc/api/v1/lan-fabric`` 34 | """ 35 | 36 | def __init__(self): 37 | super().__init__() 38 | self.class_name = self.__class__.__name__ 39 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 40 | self.lan_fabric = f"{self.v1}/lan-fabric" 41 | self.log.debug("ENTERED api.v1.lan-fabric.LanFabric()") 42 | -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/lan_fabric/rest/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/lan_fabric/rest/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/lan_fabric/rest/control/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/lan_fabric/rest/control/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/lan_fabric/rest/control/control.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # pylint: disable=line-too-long 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..rest import Rest 23 | 24 | 25 | class Control(Rest): 26 | """ 27 | ## api.v1.lan_fabric.rest.control.Control() 28 | 29 | ### Description 30 | Common methods and properties for Control() subclasses. 31 | 32 | ### Path 33 | - ``/api/v1/lan-fabric/rest/control`` 34 | """ 35 | 36 | def __init__(self): 37 | super().__init__() 38 | self.class_name = self.__class__.__name__ 39 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 40 | self.control = f"{self.rest}/control" 41 | msg = f"ENTERED api.v1.lan_fabric.rest.control.{self.class_name}" 42 | self.log.debug(msg) 43 | -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/lan_fabric/rest/control/fabrics/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/lan_fabric/rest/control/fabrics/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/lan_fabric/rest/control/switches/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/lan_fabric/rest/control/switches/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/lan_fabric/rest/inventory/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/common/api/v1/lan_fabric/rest/inventory/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/lan_fabric/rest/rest.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # pylint: disable=line-too-long 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..lan_fabric import LanFabric 23 | 24 | 25 | class Rest(LanFabric): 26 | """ 27 | ## api.v1.lan_fabric.rest.Rest() 28 | 29 | ### Description 30 | Common methods and properties for api.v1.lan_fabric.rest.Rest() subclasses. 31 | 32 | ### Path 33 | - ``/api/v1/lan-fabric/rest`` 34 | """ 35 | 36 | def __init__(self): 37 | super().__init__() 38 | self.class_name = self.__class__.__name__ 39 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 40 | self.rest = f"{self.lan_fabric}/rest" 41 | msg = f"ENTERED api.v1.lan_fabric.rest.{self.class_name}" 42 | self.log.debug(msg) 43 | -------------------------------------------------------------------------------- /plugins/module_utils/common/api/v1/v1.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..api import Api 23 | 24 | 25 | class V1(Api): 26 | """ 27 | ## v1 API enpoints - Api().V1() 28 | 29 | ### Description 30 | Common methods and properties for API v1 subclasses. 31 | 32 | ### Path 33 | ``/appcenter/cisco/ndfc/api/v1/`` 34 | """ 35 | 36 | def __init__(self): 37 | super().__init__() 38 | self.class_name = self.__class__.__name__ 39 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 40 | self.log.debug("ENTERED api.v1.V1()") 41 | self.v1 = f"{self.api}/v1" 42 | -------------------------------------------------------------------------------- /plugins/module_utils/common/ep/nexus/api/api.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..nexus import Nexus 23 | 24 | 25 | class Api(Nexus): 26 | """ 27 | ## Nexus Dashboard enpoints - Nexus().Api() 28 | 29 | ### Description 30 | Common methods and properties for ND subclasses. 31 | 32 | ### Path 33 | ``/nexus/api`` 34 | """ 35 | 36 | def __init__(self): 37 | super().__init__() 38 | self.class_name = self.__class__.__name__ 39 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 40 | self.api = f"{self.nexus}/api" 41 | 42 | msg = "ENTERED ep.nexus.api.Api()" 43 | self.log.debug(msg) 44 | -------------------------------------------------------------------------------- /plugins/module_utils/common/ep/nexus/api/federation/federation.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ansible_collections.cisco.dcnm.plugins.module_utils.common.ep.nexus.api.api import Api 23 | 24 | 25 | class Federation(Api): 26 | """ 27 | ## v1 API enpoints - Api().V1() 28 | 29 | ### Description 30 | Common methods and properties for API v1 subclasses. 31 | 32 | ### Path 33 | ``/nexus/api/federation`` 34 | """ 35 | 36 | def __init__(self): 37 | super().__init__() 38 | self.class_name = self.__class__.__name__ 39 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 40 | self.federation = f"{self.api}/federation" 41 | 42 | msg = "ENTERED ep.nexus.api.federation.Federation()" 43 | self.log.debug(msg) 44 | -------------------------------------------------------------------------------- /plugins/module_utils/common/ep/nexus/api/federation/v4/federations/federations.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..v4 import V4 23 | 24 | 25 | class EpFederationsList(V4): 26 | """ 27 | ## EpFederationMembers()- Nexus().Api().Federation.V4.Federations() 28 | 29 | ### Description 30 | Return FederationMembers endpoint information 31 | 32 | ### Path 33 | ``/nexus/api/federation/v4/federations/members`` 34 | 35 | ### Verb 36 | ``GET`` 37 | """ 38 | def __init__(self): 39 | super().__init__() 40 | self.class_name = self.__class__.__name__ 41 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 42 | 43 | self.path = f"{self.v4}/federations" 44 | self.verb = "GET" 45 | msg = "ENTERED ep.nexus.api.federation.v4.federations." 46 | msg += "EpFederationsList()" 47 | self.log.debug(msg) 48 | -------------------------------------------------------------------------------- /plugins/module_utils/common/ep/nexus/api/federation/v4/members/members.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..v4 import V4 23 | 24 | 25 | class EpFederationMembersList(V4): 26 | """ 27 | ## EpFederationMembers()- Nexus().Api().Federation.V4.EpFederationMembers() 28 | 29 | ### Description 30 | Return FederationMembers endpoint information 31 | 32 | ### Path 33 | ``/nexus/api/federation/v4/members`` 34 | 35 | ### Verb 36 | ``GET`` 37 | """ 38 | def __init__(self): 39 | super().__init__() 40 | self.class_name = self.__class__.__name__ 41 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 42 | 43 | self.path = f"{self.v4}/members" 44 | self.verb = "GET" 45 | msg = "ENTERED ep.nexus.api.federation.v4.members." 46 | msg += "EpFederationMembersList()" 47 | self.log.debug(msg) 48 | -------------------------------------------------------------------------------- /plugins/module_utils/common/ep/nexus/api/federation/v4/v4.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ..federation import Federation 23 | 24 | 25 | class V4(Federation): 26 | """ 27 | ## v1 API enpoints - Api().V1() 28 | 29 | ### Description 30 | Common methods and properties for API v1 subclasses. 31 | 32 | ### Path 33 | ``/nexus/api/federation/v4`` 34 | """ 35 | 36 | def __init__(self): 37 | super().__init__() 38 | self.class_name = self.__class__.__name__ 39 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 40 | self.v4 = f"{self.federation}/v4" 41 | 42 | msg = "ENTERED ep.nexus.api.federation.v4.V4()" 43 | self.log.debug(msg) 44 | -------------------------------------------------------------------------------- /plugins/module_utils/common/ep/nexus/nexus.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | import logging 21 | 22 | from ...conversion import ConversionUtils 23 | 24 | 25 | class Nexus: 26 | """ 27 | ## ND API endpoints - Nexus() 28 | 29 | ### Description 30 | Common methods and properties for ND API subclasses. 31 | 32 | ### Path 33 | ``/nexus`` 34 | """ 35 | 36 | def __init__(self): 37 | self.class_name = self.__class__.__name__ 38 | self.log = logging.getLogger(f"dcnm.{self.class_name}") 39 | self.conversion = ConversionUtils() 40 | # Popuate in subclasses to indicate which properties 41 | # are mandatory for the subclass. 42 | self.required_properties = set() 43 | self.nexus = "/nexus" 44 | self._path = None 45 | self._verb = None 46 | 47 | msg = "ENTERED ep.nexus.Nexus()" 48 | self.log.debug(msg) 49 | 50 | @property 51 | def path(self): 52 | """ 53 | Return the endpoint path. 54 | """ 55 | return self._path 56 | 57 | @path.setter 58 | def path(self, value): 59 | self._path = value 60 | 61 | @property 62 | def verb(self): 63 | """ 64 | Return the endpoint verb. 65 | """ 66 | return self._verb 67 | 68 | @verb.setter 69 | def verb(self, value): 70 | self._verb = value 71 | -------------------------------------------------------------------------------- /plugins/module_utils/common/exceptions.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | __author__ = "Allen Robel" 19 | 20 | 21 | class ControllerResponseError(Exception): 22 | """ 23 | Used to raise an exception when the controller returns a non-200 response. 24 | """ 25 | 26 | pass 27 | -------------------------------------------------------------------------------- /plugins/module_utils/common/logging_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "formatters": { 4 | "standard": { 5 | "class": "logging.Formatter", 6 | "format": "%(asctime)s - %(levelname)s - [%(name)s.%(funcName)s.%(lineno)d] %(message)s" 7 | } 8 | }, 9 | "handlers": { 10 | "file": { 11 | "class": "logging.handlers.RotatingFileHandler", 12 | "formatter": "standard", 13 | "level": "DEBUG", 14 | "filename": "/tmp/dcnm.log", 15 | "mode": "a", 16 | "encoding": "utf-8", 17 | "maxBytes": 50000000, 18 | "backupCount": 4 19 | } 20 | }, 21 | "loggers": { 22 | "dcnm": { 23 | "handlers": [ 24 | "file" 25 | ], 26 | "level": "DEBUG", 27 | "propagate": false 28 | } 29 | }, 30 | "root": { 31 | "level": "INFO", 32 | "handlers": [ 33 | "file" 34 | ] 35 | } 36 | } -------------------------------------------------------------------------------- /plugins/module_utils/fabric/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/fabric/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/image_policy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/image_policy/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/image_upgrade/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/image_upgrade/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/network/dcnm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/module_utils/network/dcnm/__init__.py -------------------------------------------------------------------------------- /plugins/modules/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/plugins/modules/__init__.py -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | ansible 2 | requests 3 | -------------------------------------------------------------------------------- /test-requirements.txt: -------------------------------------------------------------------------------- 1 | black==24.3.0 ; python_version > '3.5' 2 | flake8 3 | pexpect 4 | yamllint 5 | pytest-xdist 6 | coverage==4.5.4 7 | -------------------------------------------------------------------------------- /tests/.gitignore: -------------------------------------------------------------------------------- 1 | output/ -------------------------------------------------------------------------------- /tests/config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | modules: 3 | python_requires: ">=3.9" 4 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_bootflash/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" 3 | switch1_file1: air.ndfc_ut 4 | switch1_file2: earth.ndfc_ut 5 | switch1_file3: fire.ndfc_ut 6 | switch1_file4: water.ndfc_ut 7 | switch2_file1: black.ndfc_ut 8 | switch2_file2: blue.ndfc_ut 9 | switch2_file3: green.ndfc_ut 10 | switch2_file4: red.ndfc_ut 11 | wildcard_filepath: "*:/*.ndfc_ut" 12 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_bootflash/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: [] 2 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_bootflash/tasks/dcnm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: collect dcnm test cases 3 | find: 4 | paths: "{{ role_path }}/tests" 5 | patterns: "{{ testcase }}.yaml" 6 | connection: local 7 | register: dcnm_cases 8 | 9 | - set_fact: 10 | test_cases: 11 | files: "{{ dcnm_cases.files }}" 12 | 13 | - name: set test_items 14 | set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" 15 | 16 | - name: run test cases (connection=httpapi) 17 | include_tasks: "{{ test_case_to_run }}" 18 | with_items: "{{ test_items }}" 19 | loop_control: 20 | loop_var: test_case_to_run 21 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_bootflash/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - { include_tasks: dcnm.yaml, tags: ['dcnm'] } 3 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_fabric/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_fabric/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: [] 2 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_fabric/tasks/dcnm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: collect dcnm test cases 3 | find: 4 | paths: "{{ role_path }}/tests" 5 | patterns: "{{ testcase }}.yaml" 6 | connection: local 7 | register: dcnm_cases 8 | 9 | - set_fact: 10 | test_cases: 11 | files: "{{ dcnm_cases.files }}" 12 | 13 | - name: set test_items 14 | set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" 15 | 16 | - name: run test cases (connection=httpapi) 17 | include_tasks: "{{ test_case_to_run }}" 18 | with_items: "{{ test_items }}" 19 | loop_control: 20 | loop_var: test_case_to_run 21 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_fabric/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - { include_tasks: dcnm.yaml, tags: ['dcnm'] } 3 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_image_policy/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_image_policy/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: [] 2 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_image_policy/tasks/dcnm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: collect dcnm test cases 3 | find: 4 | paths: "{{ role_path }}/tests" 5 | patterns: "{{ testcase }}.yaml" 6 | connection: local 7 | register: dcnm_cases 8 | 9 | - set_fact: 10 | test_cases: 11 | files: "{{ dcnm_cases.files }}" 12 | 13 | - name: set test_items 14 | set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" 15 | 16 | - name: run test cases (connection=httpapi) 17 | include_tasks: "{{ test_case_to_run }}" 18 | with_items: "{{ test_items }}" 19 | loop_control: 20 | loop_var: test_case_to_run 21 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_image_policy/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - { include_tasks: dcnm.yaml, tags: ['dcnm'] } 3 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_image_upgrade/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_image_upgrade/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: [] 2 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_image_upgrade/tasks/dcnm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: collect dcnm test cases 3 | find: 4 | paths: "{{ role_path }}/tests" 5 | patterns: "{{ testcase }}.yaml" 6 | connection: local 7 | register: dcnm_cases 8 | 9 | - set_fact: 10 | test_cases: 11 | files: "{{ dcnm_cases.files }}" 12 | 13 | - name: set test_items 14 | set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" 15 | 16 | - name: run test cases (connection=httpapi) 17 | include_tasks: "{{ test_case_to_run }}" 18 | with_items: "{{ test_items }}" 19 | loop_control: 20 | loop_var: test_case_to_run 21 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_image_upgrade/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - { include_tasks: dcnm.yaml, tags: ['dcnm'] } -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_image_upgrade/tests/01_setup_add_switches_to_fabric.yaml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # TESTCASE: 3 | # 4 | # 01_add_switches_to_fabric 5 | # 6 | # Description: 7 | # 8 | # Add 1x Spine and 2x Leafs to Fabric. 9 | # 10 | ################################################################################ 11 | # 12 | ################################################################################ 13 | # RUNTIME 14 | ################################################################################ 15 | # 16 | # Recent run times (MM:SS.ms): 17 | # 02:20.4434 18 | # 19 | ################################################################################ 20 | # STEPS 21 | ################################################################################ 22 | # 23 | - name: SETUP - Add 1x Spine and 2x Leafs to Fabric. 24 | cisco.dcnm.dcnm_inventory: 25 | fabric: "{{ fabric_name_1 }}" 26 | state: merged 27 | config: 28 | - seed_ip: "{{ ansible_switch_1 }}" 29 | auth_proto: MD5 30 | user_name: "{{ switch_username }}" 31 | password: "{{ switch_password }}" 32 | max_hops: 0 33 | role: leaf 34 | preserve_config: True 35 | - seed_ip: "{{ ansible_switch_2 }}" 36 | auth_proto: MD5 37 | user_name: "{{ switch_username }}" 38 | password: "{{ switch_password }}" 39 | max_hops: 0 40 | role: leaf 41 | preserve_config: True 42 | - seed_ip: "{{ ansible_switch_3 }}" 43 | auth_proto: MD5 44 | user_name: "{{ switch_username }}" 45 | password: "{{ switch_password }}" 46 | max_hops: 0 47 | role: spine 48 | preserve_config: True 49 | register: result 50 | 51 | - assert: 52 | that: 53 | - result.changed == true 54 | 55 | - assert: 56 | that: 57 | - item["RETURN_CODE"] == 200 58 | loop: '{{ result.response }}' 59 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_image_upload/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" 3 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_image_upload/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: [] 2 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_image_upload/tasks/dcnm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: collect dcnm test cases 3 | find: 4 | paths: "{{ role_path }}/tests/dcnm" 5 | patterns: "{{ testcase }}.yaml" 6 | connection: local 7 | register: dcnm_cases 8 | 9 | - set_fact: 10 | test_cases: 11 | files: "{{ dcnm_cases.files }}" 12 | 13 | - name: set test_items 14 | set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" 15 | 16 | - name: run test cases (connection=httpapi) 17 | include: "{{ test_case_to_run }}" 18 | with_items: "{{ test_items }}" 19 | loop_control: 20 | loop_var: test_case_to_run 21 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_image_upload/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - { include: dcnm.yaml, tags: ['dcnm'] } -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_interface/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" 3 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_interface/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - prepare_dcnm_intf -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_interface/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - { include: dcnm.yaml, tags: ['dcnm'] } -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_inventory/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_inventory/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: [] -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_inventory/tasks/dcnm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: collect dcnm test cases 3 | find: 4 | paths: "{{ role_path }}/tests/dcnm" 5 | patterns: "{{ testcase }}.yaml" 6 | connection: local 7 | register: dcnm_cases 8 | tags: sanity 9 | 10 | - set_fact: 11 | test_cases: 12 | files: "{{ dcnm_cases.files }}" 13 | tags: sanity 14 | 15 | - name: set test_items 16 | set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" 17 | tags: sanity 18 | 19 | - name: run test cases (connection=httpapi) 20 | include: "{{ test_case_to_run }}" 21 | with_items: "{{ test_items }}" 22 | loop_control: 23 | loop_var: test_case_to_run 24 | tags: sanity 25 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_inventory/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - set_fact: 4 | controller_version: "Unable to determine controller version" 5 | tags: sanity 6 | 7 | - name: Determine version of DCNM or NDFC 8 | cisco.dcnm.dcnm_rest: 9 | method: GET 10 | path: /appcenter/cisco/ndfc/api/about/version 11 | register: result 12 | ignore_errors: yes 13 | tags: sanity 14 | 15 | - set_fact: 16 | controller_version: "{{ result.response['DATA']['version'][0:2] | int }}" 17 | when: ( result.response['DATA']['version'] is search("\d\d.\d+") ) 18 | ignore_errors: yes 19 | tags: sanity 20 | 21 | - name: Determine version of DCNM or NDFC 22 | cisco.dcnm.dcnm_rest: 23 | method: GET 24 | path: /fm/fmrest/about/version 25 | register: result 26 | ignore_errors: yes 27 | tags: sanity 28 | 29 | - set_fact: 30 | controller_version: "{{ result.response['DATA']['version'][0:2] | int }}" 31 | when: ( result.response['DATA']['version'] is search("\d\d.\d+") ) 32 | ignore_errors: yes 33 | tags: sanity 34 | 35 | # No need to continue if we cannot determine the DCNM/NDFC controller version 36 | - assert: 37 | that: 38 | - 'controller_version != "Unable to determine controller version"' 39 | tags: sanity 40 | 41 | - { include: dcnm.yaml, tags: ['dcnm'] } 42 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_links/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" 3 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_links/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: [prepare_dcnm_links] 2 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_links/tasks/dcnm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: collect dcnm test cases 3 | find: 4 | paths: "{{ role_path }}/tests/dcnm" 5 | patterns: "{{ testcase }}.yaml" 6 | connection: local 7 | register: dcnm_cases 8 | tags: sanity 9 | 10 | - set_fact: 11 | test_cases: 12 | files: "{{ dcnm_cases.files }}" 13 | tags: sanity 14 | 15 | - name: set test_items 16 | set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" 17 | tags: sanity 18 | 19 | - name: run test cases (connection=httpapi) 20 | include: "{{ test_case_to_run }}" 21 | with_items: "{{ test_items }}" 22 | loop_control: 23 | loop_var: test_case_to_run 24 | tags: sanity 25 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_links/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - { include: dcnm.yaml, tags: ['dcnm'] } -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_log/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_log/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: [] -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_log/tasks/dcnm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: collect dcnm test cases 3 | find: 4 | paths: ["{{ role_path }}/tests/dcnm"] 5 | patterns: "{{ testcase }}.yaml" 6 | connection: local 7 | register: dcnm_cases 8 | tags: sanity 9 | 10 | - set_fact: 11 | test_cases: 12 | files: "{{ dcnm_cases.files }}" 13 | tags: sanity 14 | 15 | - name: set test_items 16 | set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" 17 | tags: sanity 18 | 19 | - name: Debug test_items 20 | debug: 21 | var: test_items 22 | 23 | - name: Debug tesetcase 24 | debug: 25 | var: testcase 26 | 27 | - name: run test cases (connection=httpapi) 28 | include_tasks: "{{ test_case_to_run }}" 29 | with_items: "{{ test_items }}" 30 | loop_control: 31 | loop_var: test_case_to_run 32 | tags: sanity 33 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_log/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Import Role Tasks 4 | ansible.builtin.import_tasks: dcnm.yaml 5 | tags: ['dcnm'] -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_maintenance_mode/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_maintenance_mode/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: [] 2 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_maintenance_mode/tasks/dcnm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: collect dcnm test cases 3 | find: 4 | paths: "{{ role_path }}/tests" 5 | patterns: "{{ testcase }}.yaml" 6 | connection: local 7 | register: dcnm_cases 8 | 9 | - set_fact: 10 | test_cases: 11 | files: "{{ dcnm_cases.files }}" 12 | 13 | - name: set test_items 14 | set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" 15 | 16 | - name: run test cases (connection=httpapi) 17 | include_tasks: "{{ test_case_to_run }}" 18 | with_items: "{{ test_items }}" 19 | loop_control: 20 | loop_var: test_case_to_run 21 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_maintenance_mode/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - { include_tasks: dcnm.yaml, tags: ['dcnm'] } 3 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_network/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_network/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: [] -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_network/tasks/dcnm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: collect dcnm test cases 3 | find: 4 | paths: ["{{ role_path }}/tests/dcnm", "{{ role_path }}/tests/dcnm/self-contained-tests"] 5 | patterns: "{{ testcase }}.yaml" 6 | connection: local 7 | register: dcnm_cases 8 | tags: sanity 9 | 10 | - set_fact: 11 | test_cases: 12 | files: "{{ dcnm_cases.files }}" 13 | tags: sanity 14 | 15 | - name: set test_items 16 | set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" 17 | tags: sanity 18 | 19 | - name: run test cases (connection=httpapi) 20 | include_tasks: "{{ test_case_to_run }}" 21 | with_items: "{{ test_items }}" 22 | loop_control: 23 | loop_var: test_case_to_run 24 | tags: sanity 25 | 26 | - name: DELETED - Clean up any existing vrfs 27 | cisco.dcnm.dcnm_vrf: 28 | fabric: "{{ test_fabric }}" 29 | state: deleted 30 | tags: sanity 31 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_network/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - set_fact: 4 | controller_version: "Unable to determine controller version" 5 | tags: sanity 6 | 7 | - name: Determine version of DCNM or NDFC 8 | cisco.dcnm.dcnm_rest: 9 | method: GET 10 | path: /appcenter/cisco/ndfc/api/about/version 11 | register: result 12 | ignore_errors: yes 13 | tags: sanity 14 | 15 | - set_fact: 16 | controller_version: "{{ result.response['DATA']['version'][0:2] | int }}" 17 | when: ( result.response['DATA']['version'] is search("\d\d.\d+") ) 18 | ignore_errors: yes 19 | tags: sanity 20 | 21 | - name: Determine version of DCNM or NDFC 22 | cisco.dcnm.dcnm_rest: 23 | method: GET 24 | path: /fm/fmrest/about/version 25 | register: result 26 | ignore_errors: yes 27 | tags: sanity 28 | 29 | - set_fact: 30 | controller_version: "{{ result.response['DATA']['version'][0:2] | int }}" 31 | when: ( result.response['DATA']['version'] is search("\d\d.\d+") ) 32 | ignore_errors: yes 33 | tags: sanity 34 | 35 | # No need to continue if we cannot determine the DCNM/NDFC controller version 36 | - assert: 37 | that: 38 | - 'controller_version != "Unable to determine controller version"' 39 | tags: sanity 40 | 41 | - name: Remove all existing networks to start with a clean state 42 | cisco.dcnm.dcnm_network: 43 | fabric: "{{ test_fabric }}" 44 | state: deleted 45 | tags: sanity 46 | 47 | - name: Create vrfs required for this test and remove all other vrfs 48 | cisco.dcnm.dcnm_vrf: 49 | fabric: "{{ test_fabric }}" 50 | state: overridden 51 | config: 52 | - vrf_name: ansible-vrf-int1 53 | vrf_id: 9008011 54 | vlan_id: 500 55 | attach: 56 | - ip_address: "{{ ansible_switch1 }}" 57 | - ip_address: "{{ ansible_switch2 }}" 58 | deploy: true 59 | - vrf_name: Tenant-1 60 | vrf_id: 9008012 61 | vlan_id: 501 62 | attach: 63 | - ip_address: "{{ ansible_switch1 }}" 64 | - ip_address: "{{ ansible_switch2 }}" 65 | deploy: true 66 | - vrf_name: Tenant-2 67 | vrf_id: 9008013 68 | vlan_id: 502 69 | attach: 70 | - ip_address: "{{ ansible_switch1 }}" 71 | - ip_address: "{{ ansible_switch2 }}" 72 | deploy: true 73 | tags: sanity 74 | 75 | - { include_tasks: dcnm.yaml, tags: ['dcnm'] } 76 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_network/tests/dcnm/self-contained-tests/scale.yaml: -------------------------------------------------------------------------------- 1 | ############################################## 2 | ## SETUP ## 3 | ############################################## 4 | 5 | - set_fact: 6 | rest_path: "/rest/control/fabrics/{{ test_fabric }}" 7 | when: controller_version == "11" 8 | 9 | - set_fact: 10 | rest_path: "/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/{{ test_fabric }}" 11 | when: controller_version >= "12" 12 | 13 | - name: SCALE - Verify if fabric is deployed. 14 | cisco.dcnm.dcnm_rest: 15 | method: GET 16 | path: "{{ rest_path }}" 17 | register: result 18 | 19 | - assert: 20 | that: 21 | - 'result.response.DATA != None' 22 | 23 | - name: SCALE - Clean up any existing networks 24 | cisco.dcnm.dcnm_network: 25 | fabric: "{{ test_fabric }}" 26 | state: deleted 27 | 28 | - name: Dummy set fact for leaf_attach_list 29 | set_fact: 30 | leaf_net_attach: [] 31 | 32 | - name: Build list of Networks to be deployed 33 | set_fact: 34 | nets_list: "{{ nets_list|default([]) + [{ 'net_name': 'TEST_NET%03d' | format(item), 'vrf_name': 'Tenant-1', 'deploy': 'no', 'net_id': (item | int + 50000) | int, 'vlan_id': (item | int + 2000) | int, 'attach': leaf_net_attach }] }}" 35 | loop: '{{ range(0, 800) | list }}' 36 | 37 | - name: Push all Networks to DCNM 38 | cisco.dcnm.dcnm_network: 39 | fabric: '{{ test_fabric }}' 40 | state: merged 41 | config: '{{ nets_list }}' 42 | register: result 43 | 44 | - name: SCALE - Clean up existing networks 45 | cisco.dcnm.dcnm_network: &conf 46 | fabric: "{{ test_fabric }}" 47 | state: deleted 48 | 49 | - name: SCALE - conf - Idempotence 50 | cisco.dcnm.dcnm_network: *conf 51 | register: result 52 | 53 | - assert: 54 | that: 55 | - 'result.changed == false' 56 | - 'result.response|length == 0' 57 | - 'result.diff|length == 0' 58 | 59 | ################################################ 60 | #### CLEAN-UP ## 61 | ################################################ 62 | 63 | - name: SCALE - Clean up any existing networks 64 | cisco.dcnm.dcnm_network: 65 | fabric: "{{ test_fabric }}" 66 | state: deleted 67 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_network/tests/dcnm/self-contained-tests/sm_dhcp_params.yaml: -------------------------------------------------------------------------------- 1 | - name: Setup - Remove all existing networks 2 | cisco.dcnm.dcnm_network: 3 | fabric: "{{ test_fabric }}" 4 | state: deleted 5 | 6 | - name: Test dhcp parameters for state merged 7 | cisco.dcnm.dcnm_network: 8 | fabric: "{{ test_fabric }}" 9 | state: merged 10 | config: 11 | - net_name: ansible-net13 12 | vrf_name: ansible-vrf-int1 13 | net_id: 7009 14 | vlan_id: 3505 15 | gw_ip_subnet: '152.168.30.1/24' 16 | mtu_l3intf: 7600 17 | arp_suppress: False 18 | int_desc: 'test interface' 19 | is_l2only: False 20 | vlan_name: testvlan 21 | dhcp_srvr1_ip: '1.1.1.1' 22 | dhcp_srvr2_ip: '2.2.2.2' 23 | dhcp_srvr3_ip: '3.3.3.3' 24 | dhcp_srvr1_vrf: one 25 | dhcp_srvr2_vrf: two 26 | dhcp_srvr3_vrf: three 27 | dhcp_loopback_id: 0 28 | attach: 29 | - ip_address: "{{ ansible_switch1 }}" 30 | ports: [] 31 | deploy: True 32 | register: result 33 | 34 | - assert: 35 | that: 36 | - 'result.changed == true' 37 | 38 | - name: Query fabric state until networkStatus transitions to DEPLOYED state 39 | cisco.dcnm.dcnm_network: 40 | fabric: "{{ test_fabric }}" 41 | state: query 42 | register: result 43 | until: 44 | - "result.response[0].parent.networkStatus is search('DEPLOYED')" 45 | retries: 30 46 | delay: 2 47 | 48 | - assert: 49 | that: 50 | - "result.response[0].parent.networkTemplateConfig.dhcpServerAddr1 is search('1.1.1.1')" 51 | - "result.response[0].parent.networkTemplateConfig.dhcpServerAddr2 is search('2.2.2.2')" 52 | - "result.response[0].parent.networkTemplateConfig.dhcpServerAddr3 is search('3.3.3.3')" 53 | - "result.response[0].parent.networkTemplateConfig.vrfDhcp is search('one')" 54 | - "result.response[0].parent.networkTemplateConfig.vrfDhcp2 is search('two')" 55 | - "result.response[0].parent.networkTemplateConfig.vrfDhcp3 is search('three')" 56 | - "result.response[0].parent.networkTemplateConfig.loopbackId is search('0')" -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_network/tests/dcnm/self-contained-tests/sm_mcast_params.yaml: -------------------------------------------------------------------------------- 1 | - name: Setup - Remove all existing networks 2 | cisco.dcnm.dcnm_network: 3 | fabric: "{{ test_fabric }}" 4 | state: deleted 5 | 6 | - name: Test mcast parameters for state merged 7 | cisco.dcnm.dcnm_network: 8 | fabric: "{{ test_fabric }}" 9 | state: merged 10 | config: 11 | - net_name: ansible-net13 12 | vrf_name: ansible-vrf-int1 13 | net_id: 7009 14 | vlan_id: 3505 15 | gw_ip_subnet: '152.168.30.1/24' 16 | mtu_l3intf: 7600 17 | arp_suppress: False 18 | int_desc: 'test interface' 19 | is_l2only: False 20 | vlan_name: testvlan 21 | multicast_group_address: '224.5.5.5' 22 | attach: 23 | - ip_address: "{{ ansible_switch1 }}" 24 | ports: [] 25 | deploy: True 26 | register: result 27 | 28 | - assert: 29 | that: 30 | - 'result.changed == true' 31 | 32 | - name: Query fabric state until networkStatus transitions to DEPLOYED state 33 | cisco.dcnm.dcnm_network: 34 | fabric: "{{ test_fabric }}" 35 | state: query 36 | register: result 37 | until: 38 | - "result.response[0].parent.networkStatus is search('DEPLOYED')" 39 | retries: 30 40 | delay: 2 41 | 42 | - assert: 43 | that: 44 | - "result.response[0].parent.networkTemplateConfig.mcastGroup is search('224.5.5.5')" -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_policy/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" 3 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_policy/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - prepare_dcnm_policy 3 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_policy/tasks/dcnm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: collect dcnm test cases 3 | find: 4 | paths: "{{ role_path }}/tests/dcnm" 5 | patterns: "{{ testcase }}.yaml" 6 | connection: local 7 | register: dcnm_cases 8 | tags: sanity 9 | 10 | - set_fact: 11 | test_cases: 12 | files: "{{ dcnm_cases.files }}" 13 | tags: sanity 14 | 15 | - name: set test_items 16 | set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" 17 | tags: sanity 18 | 19 | - name: run test cases (connection=httpapi) 20 | ansible.builtin.include_tasks: "{{ test_case_to_run }}" 21 | with_items: "{{ test_items }}" 22 | loop_control: 23 | loop_var: test_case_to_run 24 | tags: sanity 25 | 26 | - name: Final Cleanup - delete telemetry policy that we created during init 27 | cisco.dcnm.dcnm_policy: 28 | fabric: "{{ ansible_it_fabric }}" 29 | state: deleted # only choose form [merged, deleted, query] 30 | config: 31 | - name: my_feature_telemetry 32 | - name: my_base_ospf 33 | - switch: 34 | - ip: "{{ ansible_switch1 }}" 35 | - ip: "{{ ansible_switch2 }}" 36 | register: result 37 | tags: sanity 38 | 39 | - assert: 40 | that: 41 | - 'item["RETURN_CODE"] == 200' 42 | loop: '{{ result.response }}' 43 | tags: sanity 44 | 45 | - name: Final Cleanup - delete all templates created during init 46 | cisco.dcnm.dcnm_template: 47 | state: deleted # only choose form [merged, deleted, query] 48 | config: 49 | - name: template_101 50 | - name: template_102 51 | - name: template_103 52 | - name: template_104 53 | - name: template_105 54 | - name: my_base_ospf 55 | - name: my_feature_telemetry 56 | tags: sanity 57 | 58 | register: result 59 | 60 | - assert: 61 | that: 62 | - 'item["RETURN_CODE"] == 200' 63 | loop: '{{ result.response }}' 64 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_policy/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - { ansible.builtin.include_tasks: dcnm.yaml, tags: ['dcnm'] } -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_resource_manager/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" 3 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_resource_manager/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: [] 2 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_resource_manager/tasks/dcnm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: collect dcnm test cases 3 | find: 4 | paths: "{{ role_path }}/tests/dcnm" 5 | patterns: "{{ testcase }}.yaml" 6 | connection: local 7 | register: dcnm_cases 8 | tags: sanity 9 | 10 | - set_fact: 11 | test_cases: 12 | files: "{{ dcnm_cases.files }}" 13 | tags: sanity 14 | 15 | - name: set test_items 16 | set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" 17 | tags: sanity 18 | 19 | - name: run test cases (connection=httpapi) 20 | include: "{{ test_case_to_run }}" 21 | with_items: "{{ test_items }}" 22 | loop_control: 23 | loop_var: test_case_to_run 24 | tags: sanity 25 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_resource_manager/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - { include: dcnm.yaml, tags: ['dcnm'] } -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_service_node/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_service_node/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: [] -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_service_node/tasks/dcnm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: collect dcnm test cases 3 | find: 4 | paths: "{{ role_path }}/tests/dcnm" 5 | patterns: "{{ testcase }}.yaml" 6 | connection: local 7 | register: dcnm_cases 8 | tags: sanity 9 | 10 | - set_fact: 11 | test_cases: 12 | files: "{{ dcnm_cases.files }}" 13 | tags: sanity 14 | 15 | - name: set test_items 16 | set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" 17 | tags: sanity 18 | 19 | - name: run test cases (connection=httpapi) 20 | include: "{{ test_case_to_run }} ansible_connection=httpapi connection={{ dcnm }}" 21 | with_items: "{{ test_items }}" 22 | loop_control: 23 | loop_var: test_case_to_run 24 | tags: sanity 25 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_service_node/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - set_fact: 4 | controller_version: "Unable to determine controller version" 5 | tags: sanity 6 | 7 | - name: Determine version of DCNM or NDFC 8 | cisco.dcnm.dcnm_rest: 9 | method: GET 10 | path: /appcenter/cisco/ndfc/api/about/version 11 | register: result 12 | ignore_errors: yes 13 | tags: sanity 14 | 15 | - set_fact: 16 | controller_version: "{{ result.response['DATA']['version'][0:2] | int }}" 17 | when: ( result.response['DATA']['version'] is search("\d\d.\d+") ) 18 | ignore_errors: yes 19 | tags: sanity 20 | 21 | - name: Determine version of DCNM or NDFC 22 | cisco.dcnm.dcnm_rest: 23 | method: GET 24 | path: /fm/fmrest/about/version 25 | register: result 26 | ignore_errors: yes 27 | tags: sanity 28 | 29 | - set_fact: 30 | controller_version: "{{ result.response['DATA']['version'][0:2] | int }}" 31 | when: ( result.response['DATA']['version'] is search("\d\d.\d+") ) 32 | ignore_errors: yes 33 | tags: sanity 34 | 35 | # No need to continue if we cannot determine the DCNM/NDFC controller version 36 | - assert: 37 | that: 38 | - 'controller_version != "Unable to determine controller version"' 39 | tags: sanity 40 | 41 | - { include: dcnm.yaml, tags: ['dcnm'] } 42 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_service_policy/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" 3 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_service_policy/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - prepare_dcnm_service_policy 3 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_service_policy/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - { include: dcnm.yaml, tags: ['dcnm'] } -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_service_route_peering/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" 3 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_service_route_peering/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - prepare_dcnm_service_route_peering 3 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_service_route_peering/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - { include: dcnm.yaml, tags: ['dcnm'] } -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_service_route_peering/tests/dcnm/.dcnm_service_route_peering_delete.yaml.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/tests/integration/targets/dcnm_service_route_peering/tests/dcnm/.dcnm_service_route_peering_delete.yaml.swp -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_template/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" 3 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_template/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - prepare_dcnm_template 3 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_template/tasks/dcnm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: collect dcnm test cases 3 | find: 4 | paths: "{{ role_path }}/tests/dcnm" 5 | patterns: "{{ testcase }}.yaml" 6 | connection: local 7 | register: dcnm_cases 8 | tags: sanity 9 | 10 | - set_fact: 11 | test_cases: 12 | files: "{{ dcnm_cases.files }}" 13 | tags: sanity 14 | 15 | - name: set test_items 16 | set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" 17 | tags: sanity 18 | 19 | - name: run test cases (connection=httpapi) 20 | include: "{{ test_case_to_run }}" 21 | with_items: "{{ test_items }}" 22 | loop_control: 23 | loop_var: test_case_to_run 24 | tags: sanity 25 | 26 | - name: Final cleanup - delete all policies created during init 27 | cisco.dcnm.dcnm_policy: 28 | fabric: "{{ ansible_it_fabric }}" 29 | state: deleted # only choose form [merged, deleted, query] 30 | config: 31 | - name: template_inuse_1 # name is mandatory 32 | - name: template_inuse_2 # name is mandatory 33 | - name: my_feature_telemetry 34 | - switch: 35 | - ip: "{{ ansible_switch1 }}" 36 | register: result 37 | tags: sanity 38 | 39 | - assert: 40 | that: 41 | - 'item["RETURN_CODE"] == 200' 42 | loop: '{{ result.response }}' 43 | tags: sanity 44 | 45 | - name: Final cleanup - delete all templates created during init 46 | cisco.dcnm.dcnm_template: 47 | state: deleted # only choose form [merged, deleted, query] 48 | config: 49 | - name: template_inuse_1 50 | - name: template_inuse_2 51 | - name: my_feature_telemetry 52 | tags: sanity 53 | register: result 54 | 55 | - assert: 56 | that: 57 | - 'item["RETURN_CODE"] == 200' 58 | loop: '{{ result.response }}' 59 | tags: sanity 60 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_template/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - { include: dcnm.yaml, tags: ['dcnm'] } -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_template/tests/dcnm/dcnm_template_wrong_state.yaml: -------------------------------------------------------------------------------- 1 | ############################################## 2 | ## SETUP ## 3 | ############################################## 4 | 5 | - name: Initialize the setup 6 | cisco.dcnm.dcnm_template: 7 | state: deleted # only choose form [merged, deleted, query] 8 | config: 9 | - name: template_101 10 | - name: template_102 11 | - name: template_103 12 | - name: template_104 13 | 14 | register: result 15 | 16 | - assert: 17 | that: 18 | - 'item["RETURN_CODE"] == 200' 19 | loop: '{{ result.response }}' 20 | 21 | - block: 22 | 23 | ############################################## 24 | ## MERGE ## 25 | ############################################## 26 | 27 | - name: Create templates 28 | cisco.dcnm.dcnm_template: &temp_merge 29 | state: replaced # only choose form [merged, deleted, query] 30 | config: 31 | - name: template_101 32 | description: "Template_101" 33 | tags: "internal policy 101" 34 | content: | 35 | telemetry 36 | certificate /bootflash/telegraf.crt telegraf 37 | destination-profile 38 | use-vrf management 39 | destination-group 1 40 | ip address 10.195.225.176 port 57000 protocol gRPC encoding GPB 41 | sensor-group 1 42 | data-source DME 43 | path sys/ch depth unbounded 44 | subscription 1 45 | dst-grp 1 46 | snsr-grp 1 sample-interval 10000 47 | 48 | register: result 49 | ignore_errors: yes 50 | 51 | - assert: 52 | that: 53 | - 'result.changed == false' 54 | - 'result["msg"] == "value of state must be one of: merged, deleted, query, got: replaced"' -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_vpc_pair/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" 3 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_vpc_pair/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: [prepare_dcnm_vpc_pair] 2 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_vpc_pair/tasks/dcnm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: collect dcnm test cases 3 | find: 4 | paths: "{{ role_path }}/tests/dcnm" 5 | patterns: "{{ testcase }}.yaml" 6 | connection: local 7 | register: dcnm_cases 8 | tags: sanity 9 | 10 | - set_fact: 11 | test_cases: 12 | files: "{{ dcnm_cases.files }}" 13 | tags: sanity 14 | 15 | - name: set test_items 16 | set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" 17 | tags: sanity 18 | 19 | - name: run test cases (connection=httpapi) 20 | include: "{{ test_case_to_run }}" 21 | with_items: "{{ test_items }}" 22 | loop_control: 23 | loop_var: test_case_to_run 24 | tags: sanity 25 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_vpc_pair/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - { include: dcnm.yaml, tags: ['dcnm'] } -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_vrf/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_vrf/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: [] -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_vrf/tasks/dcnm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: collect dcnm test cases 3 | find: 4 | paths: ["{{ role_path }}/tests/dcnm", "{{ role_path }}/tests/dcnm/self-contained-tests"] 5 | patterns: "{{ testcase }}.yaml" 6 | connection: local 7 | register: dcnm_cases 8 | tags: sanity 9 | 10 | - set_fact: 11 | test_cases: 12 | files: "{{ dcnm_cases.files }}" 13 | tags: sanity 14 | 15 | - name: set test_items 16 | set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" 17 | tags: sanity 18 | 19 | - name: debug 20 | debug: 21 | var: test_items 22 | 23 | - name: debug 24 | debug: 25 | var: testcase 26 | 27 | - name: run test cases (connection=httpapi) 28 | include_tasks: "{{ test_case_to_run }}" 29 | with_items: "{{ test_items }}" 30 | loop_control: 31 | loop_var: test_case_to_run 32 | tags: sanity 33 | -------------------------------------------------------------------------------- /tests/integration/targets/dcnm_vrf/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - set_fact: 4 | controller_version: "Unable to determine controller version" 5 | tags: sanity 6 | 7 | - name: Determine version of DCNM or NDFC 8 | cisco.dcnm.dcnm_rest: 9 | method: GET 10 | path: /appcenter/cisco/ndfc/api/about/version 11 | register: result 12 | ignore_errors: yes 13 | tags: sanity 14 | 15 | - set_fact: 16 | controller_version: "{{ result.response['DATA']['version'][0:2] | int }}" 17 | when: ( result.response['DATA']['version'] is search("\d\d.\d+") ) 18 | ignore_errors: yes 19 | tags: sanity 20 | 21 | - name: Determine version of DCNM or NDFC 22 | cisco.dcnm.dcnm_rest: 23 | method: GET 24 | path: /fm/fmrest/about/version 25 | register: result 26 | ignore_errors: yes 27 | tags: sanity 28 | 29 | - set_fact: 30 | controller_version: "{{ result.response['DATA']['version'][0:2] | int }}" 31 | when: ( result.response['DATA']['version'] is search("\d\d.\d+") ) 32 | ignore_errors: yes 33 | tags: sanity 34 | 35 | # No need to continue if we cannot determine the DCNM/NDFC controller version 36 | - assert: 37 | that: 38 | - 'controller_version != "Unable to determine controller version"' 39 | tags: sanity 40 | 41 | - name: Import Role Tasks 42 | ansible.builtin.import_tasks: dcnm.yaml 43 | tags: ['dcnm'] -------------------------------------------------------------------------------- /tests/integration/targets/module_integration/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "{{ testcase }}" 3 | -------------------------------------------------------------------------------- /tests/integration/targets/module_integration/meta/main.yaml: -------------------------------------------------------------------------------- 1 | dependencies: [] 2 | -------------------------------------------------------------------------------- /tests/integration/targets/module_integration/tasks/dcnm.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: collect dcnm test cases 3 | find: 4 | paths: "{{ role_path }}/tests" 5 | patterns: "{{ testcase }}.yaml" 6 | connection: local 7 | register: dcnm_cases 8 | 9 | - set_fact: 10 | test_cases: 11 | files: "{{ dcnm_cases.files }}" 12 | 13 | - name: set test_items 14 | set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" 15 | 16 | - name: run test cases (connection=httpapi) 17 | include: "{{ test_case_to_run }}" 18 | with_items: "{{ test_items }}" 19 | loop_control: 20 | loop_var: test_case_to_run 21 | -------------------------------------------------------------------------------- /tests/integration/targets/module_integration/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - { include: fabric_setup.yaml, tags: ['dcnm_setup'] } 3 | - { include: dcnm.yaml, tags: ['dcnm_integration_tests'] } 4 | -------------------------------------------------------------------------------- /tests/integration/targets/module_integration/tests/exec_vars/vrfs.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | vrfs: 3 | - vrf_name: green_red 4 | vrf_id: 470000 5 | vrf_template: Default_VRF_Universal 6 | vrf_extension_template: Default_VRF_Extension_Universal 7 | vlan_id: 201 8 | source: null 9 | service_vrf_template: null 10 | - vrf_name: engineering 11 | vrf_id: 480000 12 | vrf_template: Default_VRF_Universal 13 | vrf_extension_template: Default_VRF_Extension_Universal 14 | vlan_id: 401 15 | source: null 16 | service_vrf_template: null 17 | - vrf_name: sales 18 | vrf_id: 550000 19 | vrf_template: Default_VRF_Universal 20 | vrf_extension_template: Default_VRF_Extension_Universal 21 | vlan_id: 501 22 | source: null 23 | service_vrf_template: null 24 | -------------------------------------------------------------------------------- /tests/integration/targets/ndfc_interface/defaults/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | testcase: "*" 3 | -------------------------------------------------------------------------------- /tests/integration/targets/ndfc_interface/files/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/tests/integration/targets/ndfc_interface/files/.gitkeep -------------------------------------------------------------------------------- /tests/integration/targets/ndfc_interface/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Discover NDFC Test Cases 3 | ansible.builtin.find: 4 | paths: "{{ role_path }}/tests" 5 | patterns: "{{ testcase }}.yaml" 6 | connection: local 7 | register: ndfc_testcases 8 | 9 | - ansible.builtin.set_fact: 10 | test_cases: 11 | files: "{{ ndfc_testcases.files }}" 12 | 13 | - name: Build List of Test Items 14 | ansible.builtin.set_fact: test_items="{{ ndfc_testcases.files | map(attribute='path') | list }}" 15 | 16 | - name: Run NDFC Test Cases 17 | ansible.builtin.include_tasks: "{{ test_case_to_run }}" 18 | with_items: "{{ test_items }}" 19 | loop_control: 20 | loop_var: test_case_to_run -------------------------------------------------------------------------------- /tests/integration/targets/ndfc_interface/templates/ndfc_pc_interfaces.j2: -------------------------------------------------------------------------------- 1 | --- 2 | # This NDFC test data structure is auto-generated 3 | # DO NOT EDIT MANUALLY 4 | # 5 | 6 | - name: "{{ test_data.pc1 }}" 7 | switch: 8 | - "{{ test_data.sw1 }}" 9 | - name: "{{ test_data.eth_intf8 }}" 10 | switch: 11 | - "{{ test_data.sw1 }}" 12 | - name: "{{ test_data.eth_intf9 }}" 13 | switch: 14 | - "{{ test_data.sw1 }}" 15 | # ------------------------------ 16 | - name: "{{ test_data.pc2 }}" 17 | switch: 18 | - "{{ test_data.sw1 }}" 19 | - name: "{{ test_data.eth_intf10 }}" 20 | switch: 21 | - "{{ test_data.sw1 }}" 22 | - name: "{{ test_data.eth_intf11 }}" 23 | switch: 24 | - "{{ test_data.sw1 }}" 25 | # ------------------------------ 26 | - name: "{{ test_data.pc3 }}" 27 | switch: 28 | - "{{ test_data.sw1 }}" 29 | - name: "{{ test_data.eth_intf12 }}" 30 | switch: 31 | - "{{ test_data.sw1 }}" 32 | - name: "{{ test_data.eth_intf13 }}" 33 | switch: 34 | - "{{ test_data.sw1 }}" 35 | # ------------------------------ 36 | - name: "{{ test_data.pc4 }}" 37 | switch: 38 | - "{{ test_data.sw1 }}" 39 | - name: "{{ test_data.eth_intf14 }}" 40 | switch: 41 | - "{{ test_data.sw1 }}" 42 | - name: "{{ test_data.eth_intf15 }}" 43 | switch: 44 | - "{{ test_data.sw1 }}" 45 | -------------------------------------------------------------------------------- /tests/unit/mocks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/tests/unit/mocks/__init__.py -------------------------------------------------------------------------------- /tests/unit/module_utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/tests/unit/module_utils/__init__.py -------------------------------------------------------------------------------- /tests/unit/module_utils/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/tests/unit/module_utils/common/__init__.py -------------------------------------------------------------------------------- /tests/unit/module_utils/common/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/tests/unit/module_utils/common/api/__init__.py -------------------------------------------------------------------------------- /tests/unit/module_utils/common/api/test_api_v1_imagemanagement_rest_imagemgnt_bootflash.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | 19 | 20 | from ansible_collections.cisco.dcnm.plugins.module_utils.common.api.v1.imagemanagement.rest.imagemgnt.bootflash.bootflash import \ 21 | EpBootflashInfo 22 | from ansible_collections.cisco.dcnm.tests.unit.module_utils.common.common_utils import \ 23 | does_not_raise 24 | 25 | PATH_PREFIX = "/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/imagemgnt" 26 | 27 | 28 | def test_ep_image_mgnt_00010(): 29 | """ 30 | ### Class 31 | - EpBootflashInfo 32 | 33 | ### Summary 34 | - Verify path and verb 35 | """ 36 | with does_not_raise(): 37 | instance = EpBootflashInfo() 38 | instance.serial_number = "1234567890" 39 | assert instance.path == f"{PATH_PREFIX}/bootFlash/bootflash-info?serialNumber=1234567890" 40 | assert instance.verb == "GET" 41 | -------------------------------------------------------------------------------- /tests/unit/module_utils/common/api/test_api_v1_imagemanagement_rest_imageupgrade.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | 19 | 20 | from ansible_collections.cisco.dcnm.plugins.module_utils.common.api.v1.imagemanagement.rest.imageupgrade.imageupgrade import ( 21 | EpInstallOptions, EpUpgradeImage) 22 | from ansible_collections.cisco.dcnm.tests.unit.module_utils.common.common_utils import \ 23 | does_not_raise 24 | 25 | PATH_PREFIX = "/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/imageupgrade" 26 | 27 | 28 | def test_ep_install_options_00010(): 29 | """ 30 | ### Class 31 | - EpInstallOptions 32 | 33 | ### Summary 34 | - Verify path and verb 35 | """ 36 | with does_not_raise(): 37 | instance = EpInstallOptions() 38 | assert instance.path == f"{PATH_PREFIX}/install-options" 39 | assert instance.verb == "POST" 40 | 41 | 42 | def test_ep_upgrade_image_00010(): 43 | """ 44 | ### Class 45 | - EpUpgradeImage 46 | 47 | ### Summary 48 | - Verify path and verb 49 | """ 50 | with does_not_raise(): 51 | instance = EpUpgradeImage() 52 | assert instance.path == f"{PATH_PREFIX}/upgrade-image" 53 | assert instance.verb == "POST" 54 | -------------------------------------------------------------------------------- /tests/unit/module_utils/common/api/test_api_v1_imagemanagement_rest_stagingmanagement.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | 19 | 20 | from ansible_collections.cisco.dcnm.plugins.module_utils.common.api.v1.imagemanagement.rest.stagingmanagement.stagingmanagement import ( 21 | EpImageStage, EpImageValidate, EpStageInfo) 22 | from ansible_collections.cisco.dcnm.tests.unit.module_utils.common.common_utils import \ 23 | does_not_raise 24 | 25 | PATH_PREFIX = "/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/stagingmanagement" 26 | 27 | 28 | def test_ep_staging_management_00010(): 29 | """ 30 | ### Class 31 | - EpImageStage 32 | 33 | ### Summary 34 | - Verify path and verb 35 | """ 36 | with does_not_raise(): 37 | instance = EpImageStage() 38 | assert instance.path == f"{PATH_PREFIX}/stage-image" 39 | assert instance.verb == "POST" 40 | 41 | 42 | def test_ep_staging_management_00020(): 43 | """ 44 | ### Class 45 | - EpImageValidate 46 | 47 | ### Summary 48 | - Verify path and verb 49 | """ 50 | with does_not_raise(): 51 | instance = EpImageValidate() 52 | assert instance.path == f"{PATH_PREFIX}/validate-image" 53 | assert instance.verb == "POST" 54 | 55 | 56 | def test_ep_staging_management_00030(): 57 | """ 58 | ### Class 59 | - EpStageInfo 60 | 61 | ### Summary 62 | - Verify path and verb 63 | """ 64 | with does_not_raise(): 65 | instance = EpStageInfo() 66 | assert instance.path == f"{PATH_PREFIX}/stage-info" 67 | assert instance.verb == "GET" 68 | -------------------------------------------------------------------------------- /tests/unit/module_utils/common/fixture.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | 19 | import json 20 | import os 21 | import sys 22 | 23 | fixture_path = os.path.join(os.path.dirname(__file__), "fixtures") 24 | 25 | 26 | def load_fixture(filename): 27 | """ 28 | load test inputs from json files 29 | """ 30 | path = os.path.join(fixture_path, f"{filename}.json") 31 | 32 | try: 33 | with open(path, encoding="utf-8") as file_handle: 34 | data = file_handle.read() 35 | except IOError as exception: 36 | msg = f"Exception opening test input file {filename}.json : " 37 | msg += f"Exception detail: {exception}" 38 | print(msg) 39 | sys.exit(1) 40 | 41 | try: 42 | fixture = json.loads(data) 43 | except json.JSONDecodeError as exception: 44 | msg = "Exception reading JSON contents in " 45 | msg += f"test input file {filename}.json : " 46 | msg += f"Exception detail: {exception}" 47 | print(msg) 48 | sys.exit(1) 49 | 50 | return fixture 51 | -------------------------------------------------------------------------------- /tests/unit/module_utils/common/fixtures/responses_DeployMaintenanceMode.json: -------------------------------------------------------------------------------- 1 | { 2 | "test_maintenance_mode_00220a": { 3 | "DATA": { 4 | "status": "Success" 5 | }, 6 | "MESSAGE": "OK", 7 | "METHOD": "POST", 8 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/VXLAN_EVPN_Fabric/switches/FDO211218HH/deploy-maintenance-mode?waitForModeChange=true", 9 | "RETURN_CODE": 200 10 | } 11 | } -------------------------------------------------------------------------------- /tests/unit/module_utils/common/fixtures/responses_MaintenanceMode.json: -------------------------------------------------------------------------------- 1 | { 2 | "test_maintenance_mode_00220a": { 3 | "DATA": { 4 | "status": "Success" 5 | }, 6 | "MESSAGE": "OK", 7 | "METHOD": "POST", 8 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/VXLAN_Fabric/switches/FDO22180ASJ/maintenance-mode", 9 | "RETURN_CODE": 200, 10 | "sequence_number": 1 11 | }, 12 | "test_maintenance_mode_00230a": { 13 | "DATA": { 14 | "status": "Failure" 15 | }, 16 | "MESSAGE": "Internal Server Error", 17 | "METHOD": "POST", 18 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/VXLAN_Fabric/switches/FDO22180ASJ/maintenance-mode", 19 | "RETURN_CODE": 500, 20 | "sequence_number": 1 21 | } 22 | } -------------------------------------------------------------------------------- /tests/unit/module_utils/common/fixtures/responses_SenderDcnm.json: -------------------------------------------------------------------------------- 1 | { 2 | "test_sender_dcnm_00200a": { 3 | "DATA": { 4 | "status": "Configuration deployment completed." 5 | }, 6 | "MESSAGE": "OK", 7 | "METHOD": "POST", 8 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/VXLAN_Fabric/config-deploy/FDO22180ASJ?forceShowRun=False", 9 | "RETURN_CODE": 200 10 | }, 11 | "test_sender_dcnm_00210a": { 12 | "DATA": { 13 | "nvPairs": { 14 | "FABRIC_NAME": "VXLAN_Fabric" 15 | } 16 | }, 17 | "MESSAGE": "OK", 18 | "METHOD": "POST", 19 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/VXLAN_Fabric/config-deploy/FDO22180ASJ?forceShowRun=False", 20 | "RETURN_CODE": 200 21 | } 22 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/tests/unit/modules/dcnm/__init__.py -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_bootflash/fixture.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | 19 | import json 20 | import os 21 | import sys 22 | 23 | fixture_path = os.path.join(os.path.dirname(__file__), "fixtures") 24 | 25 | 26 | def load_fixture(filename): 27 | """ 28 | load test inputs from json files 29 | """ 30 | path = os.path.join(fixture_path, f"{filename}.json") 31 | 32 | try: 33 | with open(path, encoding="utf-8") as file_handle: 34 | data = file_handle.read() 35 | except IOError as exception: 36 | msg = f"Exception opening test input file {filename}.json : " 37 | msg += f"Exception detail: {exception}" 38 | print(msg) 39 | sys.exit(1) 40 | 41 | try: 42 | fixture = json.loads(data) 43 | except json.JSONDecodeError as exception: 44 | msg = "Exception reading JSON contents in " 45 | msg += f"test input file {filename}.json : " 46 | msg += f"Exception detail: {exception}" 47 | print(msg) 48 | sys.exit(1) 49 | 50 | return fixture 51 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_bootflash/fixtures/file_info_ConvertFileInfoToTarget.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked playbook configurations for query-state tests.", 4 | "tests/unit/modules/dcnm/dcnm_bootflash" 5 | ], 6 | "test_convert_file_info_to_target_00100a": { 7 | "bootflash_type": "active", 8 | "date": "Sep 19 22:20:07 2023", 9 | "deviceName": "cvd-1212-spine", 10 | "fileName": "n9000-epld.10.2.5.M.img", 11 | "filePath": "bootflash:", 12 | "ipAddr": " 192.168.1.1", 13 | "name": "bootflash:", 14 | "serialNumber": "BDY3814QDD0", 15 | "size": "218233885" 16 | }, 17 | "test_convert_file_info_to_target_00120a": { 18 | "bootflash_type": "active", 19 | "date": "Sep 19 22:20:07 2023", 20 | "deviceName": "cvd-1212-spine", 21 | "fileName": "foo", 22 | "filePath": "bootflash:", 23 | "ipAddr": " 192.168.1.1", 24 | "name": 10, 25 | "serialNumber": "BDY3814QDD0", 26 | "size": "218233885" 27 | }, 28 | "test_convert_file_info_to_target_00130a": { 29 | "bootflash_type": "active", 30 | "date": "Sep 19 22:20:07 2023", 31 | "deviceName": "cvd-1212-spine", 32 | "fileName": "foo", 33 | "filePath": "bootflash:", 34 | "ipAddr": " 192.168.1.1", 35 | "name": "bootflash", 36 | "serialNumber": "BDY3814QDD0", 37 | "size": "218233885" 38 | }, 39 | "test_convert_file_info_to_target_00210a": { 40 | "bootflash_type": "active", 41 | "date": "Sep 19 22:20:07 202", 42 | "deviceName": "cvd-1212-spine", 43 | "fileName": "foo", 44 | "filePath": "bootflash:", 45 | "ipAddr": " 192.168.1.1", 46 | "name": "bootflash:", 47 | "serialNumber": "BDY3814QDD0", 48 | "size": "218233885" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_bootflash/fixtures/responses_EpBootflashFiles.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked EpBootflashFiles() responses for tests/unit/modules/dcnm/dcnm_bootflash" 4 | ], 5 | "test_bootflash_deleted_01000a": { 6 | "DATA": "File(s) Deleted Successfully. \nDeleted files: [black.txt][air.txt]", 7 | "MESSAGE": "OK", 8 | "METHOD": "DELETE", 9 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/imagemgnt/bootFlash/bootflash-files", 10 | "RETURN_CODE": 200, 11 | "sequence_number": 1 12 | }, 13 | "test_bootflash_files_00100a": { 14 | "DATA": "File(s) Deleted Successfully. \nDeleted files: [black.txt][air.txt]", 15 | "MESSAGE": "OK", 16 | "METHOD": "DELETE", 17 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/imagemgnt/bootFlash/bootflash-files", 18 | "RETURN_CODE": 200, 19 | "sequence_number": 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_bootflash/fixtures/targets_ConvertFileInfoToTarget.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "target dictionaries used for ConvertFileInfoToTarget() unit test asserts.", 4 | "tests/unit/modules/dcnm/dcnm_bootflash/test_convert_file_info_to_target.py" 5 | ], 6 | "test_convert_file_info_to_target_00100a": { 7 | "date": "2023-09-19 22:20:07", 8 | "device_name": "cvd-1212-spine", 9 | "filepath": "bootflash:/n9000-epld.10.2.5.M.img", 10 | "ip_address": "192.168.1.1", 11 | "serial_number": "BDY3814QDD0", 12 | "size": "218233885", 13 | "supervisor": "active" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_fabric/fixture.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | 19 | import json 20 | import os 21 | import sys 22 | 23 | fixture_path = os.path.join(os.path.dirname(__file__), "fixtures") 24 | 25 | 26 | def load_fixture(filename): 27 | """ 28 | load test inputs from json files 29 | """ 30 | path = os.path.join(fixture_path, f"{filename}.json") 31 | 32 | try: 33 | with open(path, encoding="utf-8") as file_handle: 34 | data = file_handle.read() 35 | except IOError as exception: 36 | msg = f"Exception opening test input file {filename}.json : " 37 | msg += f"Exception detail: {exception}" 38 | print(msg) 39 | sys.exit(1) 40 | 41 | try: 42 | fixture = json.loads(data) 43 | except json.JSONDecodeError as exception: 44 | msg = "Exception reading JSON contents in " 45 | msg += f"test input file {filename}.json : " 46 | msg += f"Exception detail: {exception}" 47 | print(msg) 48 | sys.exit(1) 49 | 50 | return fixture 51 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_fabric/fixtures/nv_pairs_VerifyPlaybookParams.json: -------------------------------------------------------------------------------- 1 | { 2 | "test_notes": [ 3 | "Mocked fabric nvPairs for VerifyPlaybookParams() unit tests" 4 | ], 5 | "test_verify_playbook_params_00050a": { 6 | "TEST_NOTES": [ 7 | "Dependent parameters for REPLICATION_MODE are not satisfied." 8 | ], 9 | "BGP_AS": "65001", 10 | "FABRIC_NAME": "f1", 11 | "REPLICATION_MODE": "Ingress", 12 | "UNDERLAY_IS_V6": "true" 13 | }, 14 | "test_verify_playbook_params_00060a": { 15 | "TEST_NOTES": [ 16 | "Dependent parameters for REPLICATION_MODE are not satisfied." 17 | ], 18 | "BGP_AS": "65001", 19 | "FABRIC_NAME": "f1", 20 | "REPLICATION_MODE": "Ingress", 21 | "UNDERLAY_IS_V6": "true" 22 | }, 23 | "test_verify_playbook_params_00080a": { 24 | "TEST_NOTES": [ 25 | "Relevant dependent parameters are not in the controller config." 26 | ], 27 | "BGP_AS": "65001", 28 | "FABRIC_NAME": "f1", 29 | "V6_SUBNET_RANGE": "fd00::a04:0/112" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_fabric/fixtures/payloads_FabricCommon.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked payloads for FabricCommon unit tests.", 4 | "tests/unit/modules/dcnm/dcnm_fabric/test_fabric_common.py" 5 | ], 6 | "test_fabric_common_00020a": [ 7 | { 8 | "TEST_NOTES": [ 9 | "ANYCAST_GW_MAC is malformed." 10 | ], 11 | "BGP_AS": 65001, 12 | "DEPLOY": true, 13 | "FABRIC_NAME": "f1", 14 | "FABRIC_TYPE": "VXLAN_EVPN", 15 | "ANYCAST_GW_MAC": "00.54" 16 | } 17 | ], 18 | "test_fabric_common_00021a": [ 19 | { 20 | "TEST_NOTES": [ 21 | "BGP_AS is malformed." 22 | ], 23 | "BGP_AS": "65001.65536", 24 | "DEPLOY": true, 25 | "FABRIC_NAME": "f1", 26 | "FABRIC_TYPE": "VXLAN_EVPN" 27 | } 28 | ], 29 | "test_fabric_common_00100a": "NOT_A_DICT", 30 | "test_fabric_common_00110a": { 31 | "TEST_NOTES": [ 32 | "All mandatory keys are present.", 33 | "Mandatory keys are pop()'ed in unit test." 34 | ], 35 | "BGP_AS": 65000, 36 | "DEPLOY": true, 37 | "FABRIC_NAME": "f1", 38 | "FABRIC_TYPE": "VXLAN_EVPN" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_fabric/fixtures/payloads_FabricCreate.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked payloads for FabricCreateBulk unit tests.", 4 | "tests/unit/modules/dcnm/dcnm_fabric/test_fabric_create.py" 5 | ], 6 | "test_fabric_create_00020a": { 7 | "TEST_NOTES": [ 8 | "Valid payload" 9 | ], 10 | "BGP_AS": 65001, 11 | "DEPLOY": true, 12 | "FABRIC_NAME": "f1", 13 | "FABRIC_TYPE": "VXLAN_EVPN" 14 | }, 15 | "test_fabric_create_00023a": { 16 | "TEST_NOTES": [ 17 | "Valid payload" 18 | ], 19 | "BGP_AS": 65001, 20 | "DEPLOY": true, 21 | "FABRIC_NAME": "f1", 22 | "FABRIC_TYPE": "VXLAN_EVPN" 23 | }, 24 | "test_fabric_create_00025a": { 25 | "TEST_NOTES": [ 26 | "FABRIC_TYPE value is invalid" 27 | ], 28 | "BGP_AS": 65001, 29 | "DEPLOY": true, 30 | "FABRIC_NAME": "f1", 31 | "FABRIC_TYPE": "INVALID_FABRIC_TYPE" 32 | }, 33 | "test_fabric_create_00026a": { 34 | "TEST_NOTES": [ 35 | "Valid payload" 36 | ], 37 | "BGP_AS": 65001, 38 | "DEPLOY": true, 39 | "FABRIC_NAME": "f1", 40 | "FABRIC_TYPE": "VXLAN_EVPN" 41 | }, 42 | "test_fabric_create_00030a": { 43 | "TEST_NOTES": [ 44 | "Valid payload" 45 | ], 46 | "BGP_AS": 65001, 47 | "DEPLOY": true, 48 | "FABRIC_NAME": "f1", 49 | "FABRIC_TYPE": "VXLAN_EVPN" 50 | }, 51 | "test_fabric_create_00031a": { 52 | "BGP_AS": 65001, 53 | "DEPLOY": true, 54 | "FABRIC_NAME": "f1", 55 | "FABRIC_TYPE": "VXLAN_EVPN" 56 | }, 57 | "test_fabric_create_00032a": { 58 | "BGP_AS": 65001, 59 | "DEPLOY": true, 60 | "FABRIC_NAME": "f1", 61 | "FABRIC_TYPE": "VXLAN_EVPN" 62 | }, 63 | "test_fabric_create_00033a": { 64 | "BGP_AS": 65001, 65 | "DEPLOY": true, 66 | "FABRIC_NAME": "f1", 67 | "FABRIC_TYPE": "VXLAN_EVPN", 68 | "ANYCAST_GW_MAC": "00:12:34:56:78:9" 69 | } 70 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_fabric/fixtures/payloads_FabricCreateBulk.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked payloads for FabricCreateBulk unit tests.", 4 | "tests/unit/modules/dcnm/dcnm_fabric/test_fabric_create_bulk.py" 5 | ], 6 | "test_fabric_create_bulk_00020a": [ 7 | { 8 | "BGP_AS": 65001, 9 | "DEPLOY": true, 10 | "FABRIC_NAME": "f1", 11 | "FABRIC_TYPE": "VXLAN_EVPN" 12 | } 13 | ], 14 | "test_fabric_create_bulk_00025a": [ 15 | { 16 | "BGP_AS": 65001, 17 | "DEPLOY": true, 18 | "FABRIC_NAME": "f1", 19 | "FABRIC_TYPE": "INVALID_FABRIC_TYPE" 20 | } 21 | ], 22 | "test_fabric_create_bulk_00026a": [ 23 | { 24 | "BGP_AS": 65001, 25 | "DEPLOY": true, 26 | "FABRIC_NAME": "f1", 27 | "FABRIC_TYPE": "VXLAN_EVPN" 28 | } 29 | ], 30 | "test_fabric_create_bulk_00030a": [ 31 | { 32 | "BGP_AS": 65001, 33 | "DEPLOY": true, 34 | "FABRIC_NAME": "f1", 35 | "FABRIC_TYPE": "VXLAN_EVPN" 36 | } 37 | ], 38 | "test_fabric_create_bulk_00031a": [ 39 | { 40 | "BGP_AS": 65001, 41 | "DEPLOY": true, 42 | "FABRIC_NAME": "f1", 43 | "FABRIC_TYPE": "VXLAN_EVPN" 44 | } 45 | ], 46 | "test_fabric_create_bulk_00032a": [ 47 | { 48 | "BGP_AS": 65001, 49 | "DEPLOY": true, 50 | "FABRIC_NAME": "f1", 51 | "FABRIC_TYPE": "VXLAN_EVPN" 52 | } 53 | ], 54 | "test_fabric_create_bulk_00033a": [ 55 | { 56 | "BGP_AS": 65001, 57 | "DEPLOY": true, 58 | "FABRIC_NAME": "f1", 59 | "FABRIC_TYPE": "VXLAN_EVPN", 60 | "ANYCAST_GW_MAC": "00:12:34:56:78:9" 61 | } 62 | ] 63 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_fabric/fixtures/payloads_FabricCreateCommon.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked payloads for FabricCreateBulk unit tests.", 4 | "tests/unit/modules/dcnm/dcnm_fabric/test_fabric_create_common.py" 5 | ], 6 | "test_fabric_create_common_00030a": { 7 | "TEST_NOTES": [ 8 | "FABRIC_TYPE is invalid." 9 | ], 10 | "BGP_AS": 65000, 11 | "DEPLOY": true, 12 | "FABRIC_NAME": "f1", 13 | "FABRIC_TYPE": "INVALID_FABRIC_TYPE" 14 | }, 15 | "test_fabric_create_common_00031a": { 16 | "TEST_NOTES": [ 17 | "Valid payload." 18 | ], 19 | "BGP_AS": 65000, 20 | "DEPLOY": true, 21 | "FABRIC_NAME": "f1", 22 | "FABRIC_TYPE": "VXLAN_EVPN" 23 | }, 24 | "test_fabric_create_common_00032a": { 25 | "TEST_NOTES": [ 26 | "Valid payload." 27 | ], 28 | "BGP_AS": 65000, 29 | "DEPLOY": true, 30 | "FABRIC_NAME": "f1", 31 | "FABRIC_TYPE": "VXLAN_EVPN" 32 | }, 33 | "test_fabric_create_common_00033a": { 34 | "TEST_NOTES": [ 35 | "Valid payload." 36 | ], 37 | "BGP_AS": 65000, 38 | "DEPLOY": true, 39 | "FABRIC_NAME": "f1", 40 | "FABRIC_TYPE": "VXLAN_EVPN" 41 | }, 42 | "test_fabric_create_common_00040a": { 43 | "TEST_NOTES": [ 44 | "Valid payload." 45 | ], 46 | "BGP_AS": 65000, 47 | "DEPLOY": true, 48 | "FABRIC_NAME": "f1", 49 | "FABRIC_TYPE": "VXLAN_EVPN" 50 | }, 51 | "test_fabric_create_common_00050a": { 52 | "TEST_NOTES": [ 53 | "Valid payload." 54 | ], 55 | "BGP_AS": 65000, 56 | "DEPLOY": true, 57 | "FABRIC_NAME": "f1", 58 | "FABRIC_TYPE": "VXLAN_EVPN" 59 | } 60 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_fabric/fixtures/payloads_FabricReplacedBulk.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked payloads for FabricCreateBulk unit tests.", 4 | "tests/unit/modules/dcnm/dcnm_fabric/test_fabric_replaced_bulk.py" 5 | ], 6 | "test_fabric_replaced_bulk_00020a": [ 7 | { 8 | "BGP_AS": 65001, 9 | "DEPLOY": true, 10 | "FABRIC_NAME": "f1", 11 | "FABRIC_TYPE": "VXLAN_EVPN" 12 | } 13 | ], 14 | "test_fabric_replaced_bulk_00024a": [ 15 | { 16 | "BGP_AS": 65001, 17 | "DEPLOY": true, 18 | "FABRIC_NAME": "f1", 19 | "FABRIC_TYPE": "VXLAN_EVPN" 20 | }, 21 | { 22 | "BGP_AS": 65001, 23 | "DEPLOY": true, 24 | "FABRIC_NAME": "f2", 25 | "FABRIC_TYPE": "VXLAN_EVPN_MSD" 26 | }, 27 | { 28 | "DEPLOY": true, 29 | "FABRIC_NAME": "f3", 30 | "FABRIC_TYPE": "LAN_CLASSIC" 31 | } 32 | ], 33 | "test_fabric_replaced_bulk_00030a": [ 34 | { 35 | "ANYCAST_GW_MAC": "0001aabbccdd", 36 | "BGP_AS": 65001, 37 | "DEPLOY": true, 38 | "FABRIC_NAME": "f1", 39 | "FABRIC_TYPE": "VXLAN_EVPN", 40 | "DEFAULT_QUEUING_POLICY_CLOUDSCALE": "a", 41 | "DEFAULT_QUEUING_POLICY_OTHER": "b", 42 | "DEFAULT_QUEUING_POLICY_R_SERIES": "c", 43 | "STATIC_UNDERLAY_IP_ALLOC": false, 44 | "VPC_DELAY_RESTORE_TIME": 300 45 | } 46 | ] 47 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_fabric/fixtures/responses_ConfigDeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "test_notes": [ 3 | "Mocked responses for config_deploy requests" 4 | ], 5 | "test_placeholder_00000a": { 6 | "TEST_NOTES": [ 7 | "Placeholder for DEPLOYMENT_FREEZE test" 8 | ], 9 | "DATA": "Operation is not allowed as NDFC/Fabric is in freeze mode", 10 | "MESSAGE": "Internal Server Error", 11 | "METHOD": "POST", 12 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/rest/control/fabrics/LAN_CLASSIC_1/config-deploy?forceShowRun=false", 13 | "RETURN_CODE": 500, 14 | "sequence_number": 3 15 | }, 16 | "test_fabric_update_bulk_00035a": { 17 | "DATA": { 18 | "status": "Configuration deployment completed." 19 | }, 20 | "MESSAGE": "OK", 21 | "METHOD": "POST", 22 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/rest/control/fabrics/f1/config-deploy?forceShowRun=false", 23 | "RETURN_CODE": 200 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_fabric/fixtures/responses_ConfigSave.json: -------------------------------------------------------------------------------- 1 | { 2 | "test_notes": [ 3 | "Mocked responses for config_save requests" 4 | ], 5 | "test_fabric_update_bulk_00031a": { 6 | "DATA": { 7 | "status": "Config save is completed" 8 | }, 9 | "MESSAGE": "OK", 10 | "METHOD": "POST", 11 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/rest/control/fabrics/f1/config-save", 12 | "RETURN_CODE": 200 13 | }, 14 | "test_fabric_update_bulk_00035a": { 15 | "DATA": { 16 | "status": "Config save is completed" 17 | }, 18 | "MESSAGE": "OK", 19 | "METHOD": "POST", 20 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/rest/control/fabrics/f1/config-save", 21 | "RETURN_CODE": 200 22 | }, 23 | "test_fabric_update_bulk_00040a": { 24 | "DATA": { 25 | "status": "Config save is completed" 26 | }, 27 | "MESSAGE": "OK", 28 | "METHOD": "POST", 29 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/rest/control/fabrics/f1/config-save", 30 | "RETURN_CODE": 200 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_fabric/fixtures/responses_FabricCommon.json: -------------------------------------------------------------------------------- 1 | { 2 | "test_fabric_common_00030a": { 3 | "DATA": "Foo data", 4 | "MESSAGE": "Foo message", 5 | "METHOD": "FOO", 6 | "REQUEST_PATH": "Foo path", 7 | "RETURN_CODE": 200, 8 | "sequence_number": 1 9 | }, 10 | "test_fabric_common_00040a": { 11 | "DATA": "Foo data", 12 | "MESSAGE": "Not Found", 13 | "METHOD": "GET", 14 | "REQUEST_PATH": "Foo path", 15 | "RETURN_CODE": 404, 16 | "sequence_number": 1 17 | }, 18 | "test_fabric_common_00041a": { 19 | "DATA": "Foo data", 20 | "MESSAGE": "OK", 21 | "METHOD": "GET", 22 | "REQUEST_PATH": "Foo path", 23 | "RETURN_CODE": 500, 24 | "sequence_number": 1 25 | }, 26 | "test_fabric_common_00042a": { 27 | "DATA": "Foo data", 28 | "MESSAGE": "ERROR", 29 | "METHOD": "GET", 30 | "REQUEST_PATH": "Foo path", 31 | "RETURN_CODE": 200, 32 | "sequence_number": 1 33 | }, 34 | "test_fabric_common_00043a": { 35 | "DATA": "Foo data", 36 | "MESSAGE": "OK", 37 | "METHOD": "GET", 38 | "REQUEST_PATH": "Foo path", 39 | "RETURN_CODE": 200, 40 | "sequence_number": 1 41 | }, 42 | "test_fabric_common_00050a": { 43 | "DATA": "Foo data", 44 | "MESSAGE": "OK", 45 | "METHOD": "POST", 46 | "REQUEST_PATH": "Foo path", 47 | "RETURN_CODE": 200, 48 | "ERROR": "Foo error", 49 | "sequence_number": 1 50 | }, 51 | "test_fabric_common_00051a": { 52 | "DATA": "Foo data", 53 | "MESSAGE": "NOK", 54 | "METHOD": "POST", 55 | "REQUEST_PATH": "Foo path", 56 | "RETURN_CODE": 200, 57 | "sequence_number": 1 58 | }, 59 | "test_fabric_common_00052a": { 60 | "DATA": "Foo data", 61 | "MESSAGE": "OK", 62 | "METHOD": "POST", 63 | "REQUEST_PATH": "Foo path", 64 | "RETURN_CODE": 200, 65 | "sequence_number": 1 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_fabric/fixtures/responses_FabricDelete.json: -------------------------------------------------------------------------------- 1 | { 2 | "test_notes": [ 3 | "Mocked responses for FabricDelete() class" 4 | ], 5 | "test_fabric_delete_00040a": { 6 | "DATA": "Fabric 'f1' is deleted successfully!", 7 | "MESSAGE": "OK", 8 | "METHOD": "DELETE", 9 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/rest/control/fabrics/f1", 10 | "RETURN_CODE": 200, 11 | "sequence_number": 1 12 | }, 13 | "test_fabric_delete_00044a": { 14 | "DATA": "Failed to delete the fabric.", 15 | "MESSAGE": "ERROR", 16 | "METHOD": "DELETE", 17 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/rest/control/fabrics/f1", 18 | "RETURN_CODE": 500, 19 | "sequence_number": 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_fabric/fixtures/responses_FabricReplacedBulk.json: -------------------------------------------------------------------------------- 1 | { 2 | "test_fabric_replaced_bulk_00240a": { 3 | "DATA": [], 4 | "MESSAGE": "OK", 5 | "METHOD": "PUT", 6 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/rest/control/fabrics/f1/Easy_Fabric", 7 | "RETURN_CODE": 200 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_fabric/fixtures/responses_ResponseHandler.json: -------------------------------------------------------------------------------- 1 | { 2 | "test_response_handler_00040a": { 3 | "DATA": "Foo data", 4 | "MESSAGE": "Not Found", 5 | "METHOD": "GET", 6 | "REQUEST_PATH": "Foo path", 7 | "RETURN_CODE": 404, 8 | "sequence_number": 1 9 | }, 10 | "test_response_handler_00041a": { 11 | "DATA": "Foo data", 12 | "MESSAGE": "OK", 13 | "METHOD": "GET", 14 | "REQUEST_PATH": "Foo path", 15 | "RETURN_CODE": 500, 16 | "sequence_number": 1 17 | }, 18 | "test_response_handler_00042a": { 19 | "DATA": "Foo data", 20 | "MESSAGE": "ERROR", 21 | "METHOD": "GET", 22 | "REQUEST_PATH": "Foo path", 23 | "RETURN_CODE": 200, 24 | "sequence_number": 1 25 | }, 26 | "test_response_handler_00043a": { 27 | "DATA": "Foo data", 28 | "MESSAGE": "OK", 29 | "METHOD": "GET", 30 | "REQUEST_PATH": "Foo path", 31 | "RETURN_CODE": 200, 32 | "sequence_number": 1 33 | }, 34 | "test_response_handler_00050a": { 35 | "DATA": "Foo data", 36 | "MESSAGE": "OK", 37 | "METHOD": "POST", 38 | "REQUEST_PATH": "Foo path", 39 | "RETURN_CODE": 200, 40 | "ERROR": "Foo error", 41 | "sequence_number": 1 42 | }, 43 | "test_response_handler_00051a": { 44 | "DATA": "Foo data", 45 | "MESSAGE": "NOK", 46 | "METHOD": "POST", 47 | "REQUEST_PATH": "Foo path", 48 | "RETURN_CODE": 200, 49 | "sequence_number": 1 50 | }, 51 | "test_response_handler_00052a": { 52 | "DATA": "Foo data", 53 | "MESSAGE": "OK", 54 | "METHOD": "POST", 55 | "REQUEST_PATH": "Foo path", 56 | "RETURN_CODE": 200, 57 | "sequence_number": 1 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_fabric/fixtures/responses_ep_fabric_config_deploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "test_notes": [ 3 | "Mocked responses for FabricConfigDeploy() unit tests." 4 | ], 5 | "test_fabric_config_deploy_00210a": { 6 | "DATA": { 7 | "status": "Configuration deployment completed." 8 | }, 9 | "MESSAGE": "OK", 10 | "METHOD": "POST", 11 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/rest/control/fabrics/f1/config-deploy?forceShowRun=false", 12 | "RETURN_CODE": 200 13 | }, 14 | "test_fabric_config_deploy_00220a": { 15 | "DATA": { 16 | "status": "Configuration deployment failed." 17 | }, 18 | "MESSAGE": "Internal server error", 19 | "METHOD": "POST", 20 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/rest/control/fabrics/f1/config-deploy?forceShowRun=false", 21 | "RETURN_CODE": 500 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_fabric/fixtures/responses_ep_fabric_config_save.json: -------------------------------------------------------------------------------- 1 | { 2 | "test_notes": [ 3 | "Mocked responses for FabricConfigSave() unit tests." 4 | ], 5 | "test_fabric_config_save_00090a": { 6 | "DATA": { 7 | "status": "Config save is completed" 8 | }, 9 | "MESSAGE": "OK", 10 | "METHOD": "POST", 11 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/rest/control/fabrics/f1/config-save", 12 | "RETURN_CODE": 200 13 | }, 14 | "test_fabric_config_save_00100a": { 15 | "DATA": { 16 | "status": "Config save failed" 17 | }, 18 | "MESSAGE": "Internal server error", 19 | "METHOD": "POST", 20 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/rest/control/fabrics/f1/config-save", 21 | "RETURN_CODE": 500 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_policy/fixture.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | 19 | import json 20 | import os 21 | import sys 22 | 23 | fixture_path = os.path.join(os.path.dirname(__file__), "fixtures") 24 | 25 | 26 | def load_fixture(filename): 27 | """ 28 | load test inputs from json files 29 | """ 30 | path = os.path.join(fixture_path, f"{filename}.json") 31 | 32 | try: 33 | with open(path, encoding="utf-8") as file_handle: 34 | data = file_handle.read() 35 | except IOError as exception: 36 | msg = f"Exception opening test input file {filename}.json : " 37 | msg += f"Exception detail: {exception}" 38 | print(msg) 39 | sys.exit(1) 40 | 41 | try: 42 | fixture = json.loads(data) 43 | except json.JSONDecodeError as exception: 44 | msg = "Exception reading JSON contents in " 45 | msg += f"test input file {filename}.json : " 46 | msg += f"Exception detail: {exception}" 47 | print(msg) 48 | sys.exit(1) 49 | 50 | return fixture 51 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_policy/fixtures/configs_Config2Payload.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked payloads for ImagePolicyUpdate unit tests.", 4 | "tests/unit/modules/dcnm/dcnm_image_policy/test_image_policy_update_bulk.py" 5 | ], 6 | "test_image_policy_payload_00120a": { 7 | "agnostic": false, 8 | "description": "image policy of 10.3(3)F", 9 | "epld_image": "n9000-epld.10.3.2.F.img", 10 | "name": "FOO", 11 | "packages": { 12 | "install": [ 13 | "mtx-openconfig-all-2.0.0.0-10.4.1.src.rpm" 14 | ], 15 | "uninstall": [ 16 | "mtx-grpctunnel-2.1.0.0-10.4.1.lib32_64_n9000" 17 | ] 18 | }, 19 | "platform": "N9K", 20 | "release": "10.3.1_nxos64-cs_64bit", 21 | "type": "PLATFORM" 22 | }, 23 | "test_image_policy_payload_00121a": { 24 | "agnostic": false, 25 | "description": "BAR", 26 | "epld_image": "", 27 | "name": "BAR", 28 | "packages": { 29 | "install": [], 30 | "uninstall": [] 31 | }, 32 | "platform": "N9K", 33 | "release": "10.3.1_nxos64-cs_64bit" 34 | }, 35 | "test_image_policy_payload_00122a": {}, 36 | "test_image_policy_payload_00123a": { 37 | "agnostic": false, 38 | "description": "BAR", 39 | "epld_image": "", 40 | "name": "BAR", 41 | "packages": { 42 | "install": [], 43 | "uninstall": [] 44 | }, 45 | "platform": "N9K", 46 | "release": "10.3.1_nxos64-cs_64bit" 47 | } 48 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_policy/fixtures/configs_Payload2Config.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked payloads for ImagePolicyUpdate unit tests.", 4 | "tests/unit/modules/dcnm/dcnm_image_policy/test_image_policy_update_bulk.py" 5 | ], 6 | "test_image_policy_payload_00220a": { 7 | "agnostic": false, 8 | "description": "image policy of 10.3(3)F", 9 | "epld_image": "n9000-epld.10.3.2.F.img", 10 | "name": "FOO", 11 | "packages": { 12 | "install": [ 13 | "mtx-openconfig-all-2.0.0.0-10.4.1.src.rpm" 14 | ], 15 | "uninstall": [ 16 | "mtx-grpctunnel-2.1.0.0-10.4.1.lib32_64_n9000" 17 | ] 18 | }, 19 | "platform": "N9K", 20 | "release": "10.3.1_nxos64-cs_64bit", 21 | "type": "PLATFORM" 22 | }, 23 | "test_image_policy_payload_00221a": { 24 | "agnostic": false, 25 | "description": "BAR", 26 | "epld_image": "", 27 | "name": "BAR", 28 | "packages": { 29 | "install": [], 30 | "uninstall": [] 31 | }, 32 | "platform": "N9K", 33 | "release": "10.3.1_nxos64-cs_64bit", 34 | "type": "PLATFORM" 35 | }, 36 | "test_image_policy_payload_00222a": {} 37 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_policy/fixtures/payloads_Config2Payload.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked payloads for ImagePolicyUpdate unit tests.", 4 | "tests/unit/modules/dcnm/dcnm_image_policy/test_image_policy_update_bulk.py" 5 | ], 6 | "test_image_policy_payload_00120a": { 7 | "agnostic": false, 8 | "epldImgName": "n9000-epld.10.3.2.F.img", 9 | "nxosVersion": "10.3.1_nxos64-cs_64bit", 10 | "packageName": "mtx-openconfig-all-2.0.0.0-10.4.1.src.rpm", 11 | "platform": "N9K", 12 | "policyDescr": "image policy of 10.3(3)F", 13 | "policyName": "FOO", 14 | "policyType": "PLATFORM", 15 | "rpmimages": "mtx-grpctunnel-2.1.0.0-10.4.1.lib32_64_n9000" 16 | }, 17 | "test_image_policy_payload_00121a": { 18 | "agnostic": false, 19 | "epldImgName": "", 20 | "nxosVersion": "10.3.1_nxos64-cs_64bit", 21 | "platform": "N9K", 22 | "policyDescr": "BAR", 23 | "policyName": "BAR", 24 | "policyType": "PLATFORM" 25 | }, 26 | "test_image_policy_payload_00122a": {}, 27 | "test_image_policy_payload_00123a": { 28 | "agnostic": false, 29 | "epldImgName": "", 30 | "nxosVersion": "10.3.1_nxos64-cs_64bit", 31 | "platform": "N9K", 32 | "policyDescr": "BAR", 33 | "policyName": "BAR", 34 | "policyType": "PLATFORM" 35 | } 36 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_policy/fixtures/payloads_Payload2Config.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked payloads for ImagePolicyUpdate unit tests.", 4 | "tests/unit/modules/dcnm/dcnm_image_policy/test_image_policy_update_bulk.py" 5 | ], 6 | "test_image_policy_payload_00220a": { 7 | "agnostic": false, 8 | "epldImgName": "n9000-epld.10.3.2.F.img", 9 | "nxosVersion": "10.3.1_nxos64-cs_64bit", 10 | "packageName": "mtx-openconfig-all-2.0.0.0-10.4.1.src.rpm", 11 | "platform": "N9K", 12 | "policyDescr": "image policy of 10.3(3)F", 13 | "policyName": "FOO", 14 | "policyType": "PLATFORM", 15 | "rpmimages": "mtx-grpctunnel-2.1.0.0-10.4.1.lib32_64_n9000" 16 | }, 17 | "test_image_policy_payload_00221a": { 18 | "agnostic": false, 19 | "epldImgName": "", 20 | "nxosVersion": "10.3.1_nxos64-cs_64bit", 21 | "platform": "N9K", 22 | "policyDescr": "BAR", 23 | "policyName": "BAR", 24 | "policyType": "PLATFORM" 25 | }, 26 | "test_image_policy_payload_00222a": {} 27 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_policy/fixtures/responses_EpPolicyDelete.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked responses for ImagePolicyDelete unit tests.", 4 | "tests/unit/modules/dcnm/dcnm_image_policy/test_image_policy_delete.py" 5 | ], 6 | "test_image_policy_delete_00031a": { 7 | "MESSAGE": "OK", 8 | "METHOD": "DELETE", 9 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/policymgnt/policy", 10 | "RETURN_CODE": 200 11 | }, 12 | "test_image_policy_delete_00032a": { 13 | "MESSAGE": "OK", 14 | "METHOD": "DELETE", 15 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/policymgnt/policy", 16 | "RETURN_CODE": 200 17 | }, 18 | "test_image_policy_delete_00034a": { 19 | "MESSAGE": "OK", 20 | "METHOD": "DELETE", 21 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/policymgnt/policy", 22 | "RETURN_CODE": 200 23 | }, 24 | "test_image_policy_delete_00037a": { 25 | "MESSAGE": "OK", 26 | "METHOD": "DELETE", 27 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/policymgnt/policy", 28 | "RETURN_CODE": 200 29 | }, 30 | "test_image_policy_delete_00038a": { 31 | "MESSAGE": "NOK", 32 | "METHOD": "DELETE", 33 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/policymgnt/policy", 34 | "RETURN_CODE": 500 35 | } 36 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_policy/fixtures/responses_ImagePolicyCreate.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked responses for ImagePolicyCreate unit tests.", 4 | "tests/unit/modules/dcnm/dcnm_image_policy/test_image_policy_create.py" 5 | ], 6 | "test_image_policy_create_00035a": { 7 | "DATA": "Policy created successfully.", 8 | "MESSAGE": "OK", 9 | "METHOD": "POST", 10 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/policymgnt/platform-policy", 11 | "RETURN_CODE": 200 12 | }, 13 | "test_image_policy_create_00036a": { 14 | "DATA": "Internal server error.", 15 | "MESSAGE": "NOK", 16 | "METHOD": "POST", 17 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/policymgnt/platform-policy", 18 | "RETURN_CODE": 500 19 | }, 20 | "test_image_policy_create_00037a": [ 21 | { 22 | "DATA": "Policy created successfully.", 23 | "MESSAGE": "OK", 24 | "METHOD": "POST", 25 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/policymgnt/platform-policy", 26 | "RETURN_CODE": 200 27 | } 28 | ], 29 | "test_image_policy_create_00037b": [ 30 | { 31 | "DATA": "Internal server error.", 32 | "MESSAGE": "NOK", 33 | "METHOD": "POST", 34 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/policymgnt/platform-policy", 35 | "RETURN_CODE": 500 36 | } 37 | ] 38 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_policy/fixtures/responses_ImagePolicyDelete.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked responses for ImagePolicyDelete unit tests.", 4 | "tests/unit/modules/dcnm/dcnm_image_policy/test_image_policy_delete.py" 5 | ], 6 | "test_image_policy_delete_00034a": { 7 | "MESSAGE": "OK", 8 | "METHOD": "DELETE", 9 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/policymgnt/policy", 10 | "RETURN_CODE": 200 11 | }, 12 | "test_image_policy_delete_00037a": { 13 | "MESSAGE": "OK", 14 | "METHOD": "DELETE", 15 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/policymgnt/policy", 16 | "RETURN_CODE": 200 17 | }, 18 | "test_image_policy_delete_00038a": { 19 | "MESSAGE": "NOK", 20 | "METHOD": "DELETE", 21 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/policymgnt/policy", 22 | "RETURN_CODE": 500 23 | } 24 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_policy/fixtures/responses_ImagePolicyUpdate.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked responses for ImagePolicyUpdate unit tests.", 4 | "tests/unit/modules/dcnm/dcnm_image_policy/test_image_policy_update.py" 5 | ], 6 | "test_image_policy_update_00035a": { 7 | "MESSAGE": "OK", 8 | "METHOD": "POST", 9 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/policymgnt/edit-policy", 10 | "RETURN_CODE": 200 11 | }, 12 | "test_image_policy_update_00036a": { 13 | "DATA": "Internal server error.", 14 | "MESSAGE": "NOK", 15 | "METHOD": "POST", 16 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/policymgnt/edit-policy", 17 | "RETURN_CODE": 500 18 | } 19 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_policy/fixtures/result_current_RestSend.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "TEST_NOTES": [ 4 | "Mocked result_current value." 5 | ], 6 | "test_image_policy_create_00035a": { 7 | "changed": true, 8 | "success": true 9 | }, 10 | "test_image_policy_create_bulk_00035a": { 11 | "changed": true, 12 | "success": true 13 | }, 14 | "test_image_policy_replace_bulk_00035a": { 15 | "changed": true, 16 | "success": true 17 | }, 18 | "test_image_policy_replace_bulk_00036a": { 19 | "changed": false, 20 | "success": false 21 | }, 22 | "test_image_policy_update_00035a": { 23 | "changed": true, 24 | "success": true 25 | }, 26 | "test_image_policy_update_00036a": { 27 | "changed": false, 28 | "success": false 29 | }, 30 | "test_image_policy_update_bulk_00035a": { 31 | "changed": true, 32 | "success": true 33 | }, 34 | "test_image_policy_update_bulk_00036a": { 35 | "changed": false, 36 | "success": false 37 | } 38 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_policy/fixtures/results_ImagePolicyCreateBulk.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked results for ImagePolicyCreateBulk unit tests.", 4 | "tests/unit/modules/dcnm/dcnm_image_policy/test_image_policy_create_bulk.py" 5 | ], 6 | "test_image_policy_create_bulk_00037a": [ 7 | { 8 | "changed": true, 9 | "success": true 10 | } 11 | ], 12 | "test_image_policy_create_bulk_00037b": [ 13 | { 14 | "changed": false, 15 | "success": false 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_policy/fixtures/results_ImagePolicyDelete.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "TEST_NOTES": [ 4 | "Mocked results for ImagePolicyDelete unit tests.", 5 | "tests/unit/modules/dcnm/dcnm_image_policy/test_image_policy_delete.py" 6 | ], 7 | "test_image_policy_delete_00037a": { 8 | "sequence_number": 1, 9 | "changed": true, 10 | "success": true 11 | }, 12 | "test_image_policy_delete_00038a": { 13 | "sequence_number": 1, 14 | "changed": false, 15 | "success": false 16 | } 17 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_policy/fixtures/results_ImagePolicyReplaceBulk.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked results for ImagePolicyReplaceBulk unit tests.", 4 | "tests/unit/modules/dcnm/dcnm_image_policy/test_image_policy_replace_bulk.py" 5 | ], 6 | "test_image_policy_replace_bulk_00037a": [ 7 | { 8 | "changed": true, 9 | "success": true 10 | } 11 | ], 12 | "test_image_policy_replace_bulk_00037b": [ 13 | { 14 | "changed": false, 15 | "success": false 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_policy/fixtures/results_ImagePolicyUpdate.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked results for ImagePolicyUpdate unit tests.", 4 | "tests/unit/modules/dcnm/dcnm_image_policy/test_image_policy_update.py" 5 | ] 6 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_policy/fixtures/results_ImagePolicyUpdateBulk.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked results for ImagePolicyUpdateBulk unit tests.", 4 | "tests/unit/modules/dcnm/dcnm_image_policy/test_image_policy_update_bulk.py" 5 | ], 6 | "test_image_policy_update_bulk_00037a": [ 7 | { 8 | "changed": true, 9 | "success": true 10 | } 11 | ], 12 | "test_image_policy_update_bulk_00037b": [ 13 | { 14 | "changed": false, 15 | "success": false 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_upgrade/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/tests/unit/modules/dcnm/dcnm_image_upgrade/__init__.py -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_upgrade/fixture.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | 19 | import json 20 | import os 21 | import sys 22 | 23 | fixture_path = os.path.join(os.path.dirname(__file__), "fixtures") 24 | 25 | 26 | def load_fixture(filename): 27 | """ 28 | load test inputs from json files 29 | """ 30 | path = os.path.join(fixture_path, f"{filename}.json") 31 | 32 | try: 33 | with open(path, encoding="utf-8") as file_handle: 34 | data = file_handle.read() 35 | except IOError as exception: 36 | msg = f"Exception opening test input file {filename}.json : " 37 | msg += f"Exception detail: {exception}" 38 | print(msg) 39 | sys.exit(1) 40 | 41 | try: 42 | fixture = json.loads(data) 43 | except json.JSONDecodeError as exception: 44 | msg = "Exception reading JSON contents in " 45 | msg += f"test input file {filename}.json : " 46 | msg += f"Exception detail: {exception}" 47 | print(msg) 48 | sys.exit(1) 49 | 50 | return fixture 51 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_upgrade/fixtures/payloads_ep_image_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "test_image_upgrade_01020a": { 3 | "devices": [ 4 | { 5 | "policyName": "KR5M", 6 | "serialNumber": "FDO21120U5D" 7 | } 8 | ], 9 | "epldOptions": { 10 | "golden": true, 11 | "moduleNumber": 1 12 | }, 13 | "epldUpgrade": true, 14 | "issuUpgrade": false, 15 | "issuUpgradeOptions1": { 16 | "disruptive": true, 17 | "forceNonDisruptive": false, 18 | "nonDisruptive": false 19 | }, 20 | "issuUpgradeOptions2": { 21 | "biosForce": true 22 | }, 23 | "pacakgeInstall": true, 24 | "pacakgeUnInstall": false, 25 | "reboot": false, 26 | "rebootOptions": { 27 | "configReload": true, 28 | "writeErase": false 29 | } 30 | }, 31 | "test_image_upgrade_01030a": { 32 | "devices": [ 33 | { 34 | "policyName": "NR3F", 35 | "serialNumber": "FDO21120U5D" 36 | } 37 | ], 38 | "epldOptions": { 39 | "golden": false, 40 | "moduleNumber": "ALL" 41 | }, 42 | "epldUpgrade": true, 43 | "issuUpgrade": true, 44 | "issuUpgradeOptions1": { 45 | "disruptive": true, 46 | "forceNonDisruptive": false, 47 | "nonDisruptive": false 48 | }, 49 | "issuUpgradeOptions2": { 50 | "biosForce": false 51 | }, 52 | "pacakgeInstall": true, 53 | "pacakgeUnInstall": false, 54 | "reboot": false, 55 | "rebootOptions": { 56 | "configReload": false, 57 | "writeErase": false 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_image_upgrade/fixtures/responses_ep_image_validate.json: -------------------------------------------------------------------------------- 1 | { 2 | "test_image_validate_00930a": { 3 | "TEST_NOTES": [ 4 | "RETURN_CODE == 500", 5 | "MESSAGE == INTERNAL SERVER ERROR" 6 | ], 7 | "RETURN_CODE": 500, 8 | "METHOD": "POST", 9 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/stagingmanagement/validate-image", 10 | "MESSAGE": "INTERNAL SERVER ERROR", 11 | "DATA": { 12 | "status": "SUCCESS", 13 | "lastOperDataObject": [ 14 | ], 15 | "message": "" 16 | } 17 | }, 18 | "test_image_validate_00940a": { 19 | "TEST_NOTES": [], 20 | "RETURN_CODE": 200, 21 | "METHOD": "POST", 22 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/imagemanagement/rest/stagingmanagement/validate-image", 23 | "MESSAGE": "OK", 24 | "DATA": { 25 | "status": "SUCCESS", 26 | "lastOperDataObject": [ 27 | ], 28 | "message": "" 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_log/utils.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | 19 | params_error_severity = { 20 | "msg": "Message with ERROR severity.", 21 | "severity": "ERROR" 22 | } 23 | 24 | params_missing_severity = { 25 | "msg": "Message with ERROR severity.", 26 | } 27 | 28 | params_missing_msg = { 29 | "severity": "INFO" 30 | } 31 | 32 | params_invalid_severity = { 33 | "msg": "Message with FOO severity.", 34 | "severity": "FOO" 35 | } 36 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_maintenance_mode/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-dcnm/413febe80eb8c9be6ef57f491f2bc0f3fa19aee2/tests/unit/modules/dcnm/dcnm_maintenance_mode/__init__.py -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_maintenance_mode/fixture.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | 19 | import json 20 | import os 21 | import sys 22 | 23 | fixture_path = os.path.join(os.path.dirname(__file__), "fixtures") 24 | 25 | 26 | def load_fixture(filename): 27 | """ 28 | load test inputs from json files 29 | """ 30 | path = os.path.join(fixture_path, f"{filename}.json") 31 | 32 | try: 33 | with open(path, encoding="utf-8") as file_handle: 34 | data = file_handle.read() 35 | except IOError as exception: 36 | msg = f"Exception opening test input file {filename}.json : " 37 | msg += f"Exception detail: {exception}" 38 | print(msg) 39 | sys.exit(1) 40 | 41 | try: 42 | fixture = json.loads(data) 43 | except json.JSONDecodeError as exception: 44 | msg = "Exception reading JSON contents in " 45 | msg += f"test input file {filename}.json : " 46 | msg += f"Exception detail: {exception}" 47 | print(msg) 48 | sys.exit(1) 49 | 50 | return fixture 51 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_maintenance_mode/fixtures/configs_Query.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked playbook configurations for Common unit tests.", 4 | "tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_common.py", 5 | "00070a - top-level config is inherited by all switches" 6 | ], 7 | "test_dcnm_maintenance_mode_query_00100a": { 8 | "switches": [ 9 | { 10 | "ip_address": "192.168.1.2" 11 | }, 12 | { 13 | "ip_address": "192.168.1.3" 14 | } 15 | ] 16 | }, 17 | "test_dcnm_maintenance_mode_query_00300a": { 18 | "switches": [ 19 | { 20 | "ip_address": "192.168.1.2" 21 | } 22 | ] 23 | }, 24 | "test_dcnm_maintenance_mode_query_00600a": { 25 | "switches": [ 26 | { 27 | "ip_address": "192.168.1.2" 28 | } 29 | ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_maintenance_mode/fixtures/responses_EpMaintenanceModeDeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked responses for endpoint EpMaintenanceModeDeploy (deploy-maintenance-mode)", 4 | "tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_merged.py" 5 | ], 6 | "test_dcnm_maintenance_mode_merged_00100a": { 7 | "DATA": { 8 | "status": "Success" 9 | }, 10 | "MESSAGE": "OK", 11 | "METHOD": "POST", 12 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/VXLAN_EVPN_Fabric/switches/FD2222222GA/deploy-maintenance-mode", 13 | "RETURN_CODE": 200 14 | }, 15 | "test_dcnm_maintenance_mode_merged_00100b": { 16 | "DATA": { 17 | "status": "Success" 18 | }, 19 | "MESSAGE": "OK", 20 | "METHOD": "POST", 21 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/VXLAN_EVPN_Fabric/switches/FD3333333GA/deploy-maintenance-mode", 22 | "RETURN_CODE": 200 23 | }, 24 | "test_dcnm_maintenance_mode_merged_00110a": { 25 | "DATA": { 26 | "status": "Success" 27 | }, 28 | "MESSAGE": "OK", 29 | "METHOD": "POST", 30 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/VXLAN_EVPN_Fabric/switches/FD2222222GA/deploy-maintenance-mode", 31 | "RETURN_CODE": 200 32 | }, 33 | "test_dcnm_maintenance_mode_merged_00110b": { 34 | "DATA": { 35 | "status": "Success" 36 | }, 37 | "MESSAGE": "OK", 38 | "METHOD": "POST", 39 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/VXLAN_EVPN_Fabric/switches/FD3333333GA/deploy-maintenance-mode", 40 | "RETURN_CODE": 200 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_maintenance_mode/fixtures/responses_EpMaintenanceModeDisable.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked EpMaintenanceModeDisable() responses.", 4 | "tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_merged.py" 5 | ], 6 | "test_dcnm_maintenance_mode_merged_00110a": { 7 | "DATA": { 8 | "status": "Success" 9 | }, 10 | "MESSAGE": "OK", 11 | "METHOD": "DELETE", 12 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/VXLAN_EVPN_Fabric/switches/FD2222222GA/maintenance-mode", 13 | "RETURN_CODE": 200 14 | }, 15 | "test_dcnm_maintenance_mode_merged_00110b": { 16 | "DATA": { 17 | "status": "Success" 18 | }, 19 | "MESSAGE": "OK", 20 | "METHOD": "DELETE", 21 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/VXLAN_EVPN_Fabric/switches/FD3333333GA/maintenance-mode", 22 | "RETURN_CODE": 200 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/dcnm_maintenance_mode/fixtures/responses_EpMaintenanceModeEnable.json: -------------------------------------------------------------------------------- 1 | { 2 | "TEST_NOTES": [ 3 | "Mocked EpMaintenanceModeEnable() responses.", 4 | "tests/unit/modules/dcnm/dcnm_maintenance_mode/test_dcnm_maintenance_mode_merged.py" 5 | ], 6 | "test_dcnm_maintenance_mode_merged_00100a": { 7 | "DATA": { 8 | "status": "Success" 9 | }, 10 | "MESSAGE": "OK", 11 | "METHOD": "POST", 12 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/VXLAN_EVPN_Fabric/switches/FD2222222GA/maintenance-mode", 13 | "RETURN_CODE": 200 14 | }, 15 | "test_dcnm_maintenance_mode_merged_00100b": { 16 | "DATA": { 17 | "status": "Success" 18 | }, 19 | "MESSAGE": "OK", 20 | "METHOD": "POST", 21 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/VXLAN_EVPN_Fabric/switches/FD3333333GA/maintenance-mode", 22 | "RETURN_CODE": 200 23 | }, 24 | "test_dcnm_maintenance_mode_merged_00300a": { 25 | "DATA": { 26 | "status": "Success" 27 | }, 28 | "MESSAGE": "OK", 29 | "METHOD": "POST", 30 | "REQUEST_PATH": "https://172.22.150.244:443/appcenter/cisco/ndfc/api/v1/lan-fabric/rest/control/fabrics/VXLAN_EVPN_Fabric/switches/FD3333333GA/maintenance-mode", 31 | "RETURN_CODE": 200 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/fixtures/dcnm_intf_pc_have.json: -------------------------------------------------------------------------------- 1 | { 2 | "pc_have" : [ 3 | { 4 | u'policy': u'int_port_channel_trunk_host_11_1', 5 | u'interfaces': [ 6 | { 7 | u'ifName': u'port-channel300', 8 | u'serialNumber': u'SAL1819SAN8', 9 | u'nvPairs': { 10 | u'MEMBER_INTERFACES': u'e1/9', 11 | u'FABRIC_NAME': u'test_fabric', 12 | u'PO_ID': u'Port-channel300', 13 | u'MTU': u'jumbo', 14 | u'PRIORITY': u'500', 15 | u'PORTTYPE_FAST_ENABLED': u'True', 16 | u'PC_MODE': u'on', 17 | u'POLICY_DESC': u'', 18 | u'CONF': u'no shutdown', 19 | u'BPDUGUARD_ENABLED': u'True', 20 | u'ADMIN_STATE': u'True', 21 | u'POLICY_ID': u'POLICY-1844640', 22 | u'ALLOWED_VLANS': u'none', 23 | u'DESC': u'port channel acting as trunk' 24 | } 25 | }] 26 | }, 27 | { 28 | u'policy': u'int_port_channel_access_host_11_1', 29 | u'interfaces': [ 30 | { 31 | u'ifName': u'port-channel301', 32 | u'serialNumber': u'SAL1819SAN8', 33 | u'nvPairs': { 34 | u'ACCESS_VLAN': u'301', 35 | u'MEMBER_INTERFACES': u'e1/10', 36 | u'FABRIC_NAME': u'test_fabric', 37 | u'PO_ID': u'Port-channel301', 38 | u'MTU': u'default', 39 | u'PRIORITY': u'500', 40 | u'PORTTYPE_FAST_ENABLED': u'True', 41 | u'PC_MODE': u'on', 42 | u'POLICY_DESC': u'', 43 | u'CONF': u'no shutdown', 44 | u'BPDUGUARD_ENABLED': u'True', 45 | u'ADMIN_STATE': u'False', 46 | u'POLICY_ID': u'POLICY-1844740', 47 | u'DESC': u'port channel acting as access' 48 | } 49 | }] 50 | }, 51 | { 52 | u'policy': u'int_l3_port_channel', 53 | u'interfaces': [ 54 | { 55 | u'ifName': u'port-channel302', 56 | u'serialNumber': u'SAL1819SAN8', 57 | u'nvPairs': { 58 | u'INTF_VRF': u'', 59 | u'MEMBER_INTERFACES': u'e1/11', 60 | u'FABRIC_NAME': u'test_fabric', 61 | u'IP': u'10.1.1.1', 62 | u'PO_ID': u'Port-channel302', 63 | u'MTU': u'9216', 64 | u'PRIORITY': u'500', 65 | u'ROUTING_TAG': u'', 66 | u'PREFIX': u'8', 67 | u'PC_MODE': u'on', 68 | u'POLICY_DESC': u'', 69 | u'CONF': u'no shutdown', 70 | u'ADMIN_STATE': u'False', 71 | u'POLICY_ID': u'POLICY-1844840', 72 | u'DESC': u'port channel acting as l3' 73 | } 74 | }] 75 | }], 76 | } 77 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/fixtures/dcnm_intf_subint_payloads.json: -------------------------------------------------------------------------------- 1 | { 2 | "subint_merged_payloads_1" : 3 | { 4 | "MESSAGE": "OK", 5 | "REQUEST_PATH": "https://10.122.197.6:443/rest/interface?serialNumber=SAL1819SAN8&ifName=Ethernet1/30", 6 | "DATA": [ 7 | { 8 | "policy": "int_subif_11_1", 9 | "interfaces": [ 10 | { 11 | "ifName": "Ethernet1/25.1", 12 | "serialNumber": "SAL1819SAN8", 13 | "nvPairs": { 14 | "INTF_VRF": "", 15 | "CONF": "no shutdown", 16 | "FABRIC_NAME": "test_fabric", 17 | "IP": "1.1.1.1", 18 | "VLAN": "100", 19 | "MTU": "9216", 20 | "SPEED": "auto", 21 | "PRIORITY": "500", 22 | "PREFIX": "24", 23 | "ADMIN_STATE": "True", 24 | "POLICY_DESC": "", 25 | "INTF_NAME": "Ethernet1/25.1", 26 | "ROUTING_TAG": "12345", 27 | "IPv6": "", 28 | "IPv6_PREFIX": "", 29 | "DESC": "sub interface eth25/1.1 configuration", 30 | "POLICY_ID": "POLICY-1901730" 31 | } 32 | }], 33 | "skipResourceCheck": "True" 34 | }], 35 | "RETURN_CODE": 200, 36 | "METHOD": "GET" 37 | }, 38 | "subint_merged_payloads_2" : 39 | { 40 | "MESSAGE": "OK", 41 | "REQUEST_PATH": "https://10.122.197.6:443/rest/interface?serialNumber=SAL1819SAN8&ifName=Ethernet1/30", 42 | "DATA": [ 43 | { 44 | "policy": "int_subif_11_1", 45 | "interfaces": [ 46 | { 47 | "ifName": "Ethernet1/25.2", 48 | "serialNumber": "SAL1819SAN8", 49 | "nvPairs": { 50 | "INTF_VRF": "", 51 | "CONF": "no shutdown", 52 | "FABRIC_NAME": "test_fabric", 53 | "IP": "1.1.1.2", 54 | "VLAN": "101", 55 | "MTU": "9216", 56 | "SPEED": "auto", 57 | "PRIORITY": "500", 58 | "PREFIX": "24", 59 | "ADMIN_STATE": "True", 60 | "POLICY_DESC": "", 61 | "INTF_NAME": "Ethernet1/25.2", 62 | "ROUTING_TAG": "12345", 63 | "IPv6": "", 64 | "IPv6_PREFIX": "", 65 | "DESC": "sub interface eth1/25.2 configuration", 66 | "POLICY_ID": "POLICY-1901720" 67 | } 68 | }], 69 | "skipResourceCheck": "True" 70 | }], 71 | "RETURN_CODE": 200, 72 | "METHOD": "GET" 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/fixtures/dcnm_intf_svi_payloads.json: -------------------------------------------------------------------------------- 1 | { 2 | "svi_merged_payloads" : 3 | { 4 | "MESSAGE": "OK", 5 | "REQUEST_PATH": "https://10.122.197.6:443/rest/interface?serialNumber=SAL1819SAN8&ifName=vlan1001", 6 | "DATA": [ 7 | { 8 | "interfaceType": "INTERFACE_VLAN", 9 | "interfaces": [ 10 | { 11 | "fabricName": "test_fabric", 12 | "ifName": "vlan1001", 13 | "interfaceType": "INTERFACE_VLAN", 14 | "nvPairs": { 15 | "ADMIN_STATE": "true", 16 | "CONF": "no shutdown", 17 | "DESC": "Switched vlan interface 1001", 18 | "DISABLE_IP_REDIRECTS": "true", 19 | "ENABLE_HSRP": "true", 20 | "ENABLE_NETFLOW": "false", 21 | "HSRP_GROUP": "10", 22 | "HSRP_PRIORITY": "5", 23 | "HSRP_VERSION": "1", 24 | "HSRP_VIP": "192.168.2.100", 25 | "INTF_NAME": "vlan1001", 26 | "INTF_VRF": "blue", 27 | "IP": "192.168.2.1", 28 | "MAC": "0000.0101.ac0a", 29 | "MTU": "9216", 30 | "NETFLOW_MONITOR": "", 31 | "PREEMPT": "true", 32 | "PREFIX": "24", 33 | "ROUTING_TAG": "1001", 34 | "advSubnetInUnderlay": "true", 35 | "dhcpServerAddr1": "192.200.1.1", 36 | "dhcpServerAddr2": "192.200.1.2", 37 | "dhcpServerAddr3": "192.200.1.3", 38 | "vrfDhcp1": "blue", 39 | "vrfDhcp2": "blue", 40 | "vrfDhcp3": "blue" 41 | }, 42 | "serialNumber": "SAL1819SAN8" 43 | } 44 | ], 45 | "policy": "int_vlan", 46 | "skipResourceCheck": "false" 47 | }], 48 | "RETURN_CODE": 200, 49 | "METHOD": "GET" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/unit/modules/dcnm/fixtures/dcnm_vpc_pair/dcnm_vpc_pair_common.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Cisco and/or its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import, division, print_function 16 | 17 | __metaclass__ = type 18 | 19 | import pytest 20 | from ansible_collections.ansible.netcommon.tests.unit.modules.utils import ( 21 | AnsibleFailJson, 22 | ) 23 | 24 | from ansible_collections.cisco.dcnm.plugins.modules.dcnm_vpc_pair import ( 25 | DcnmVpcPair, 26 | ) 27 | 28 | 29 | class MockAnsibleModule: 30 | """ 31 | Mock the AnsibleModule class 32 | """ 33 | 34 | params = { 35 | "config": [], 36 | "state": "merged", 37 | "templates": [], 38 | "src_fabric": "mmudigon", 39 | "deploy": True, 40 | } 41 | supports_check_mode = True 42 | 43 | @staticmethod 44 | def fail_json(msg, **kwargs) -> AnsibleFailJson: 45 | """ 46 | mock the fail_json method 47 | """ 48 | raise AnsibleFailJson(msg, kwargs) 49 | 50 | 51 | @pytest.fixture(name="dcnm_vpc_pair_fixture") 52 | def dcnm_vpc_pair_fixture(monkeypatch): 53 | """ 54 | mock DcnmVpcPair 55 | """ 56 | 57 | return DcnmVpcPair(MockAnsibleModule) 58 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | minversion = 1.4.2 3 | envlist = linters 4 | skipsdist = True 5 | 6 | [testenv] 7 | deps = -r{toxinidir}/requirements.txt 8 | -r{toxinidir}/test-requirements.txt 9 | 10 | [testenv:black] 11 | install_command = pip install {opts} {packages} 12 | commands = 13 | black -v -l160 {toxinidir} 14 | 15 | [testenv:linters] 16 | install_command = pip install {opts} {packages} 17 | commands = 18 | black -v -l160 --check {toxinidir} 19 | flake8 {posargs} 20 | 21 | [testenv:venv] 22 | commands = {posargs} 23 | 24 | [flake8] 25 | # E123, E125 skipped as they are invalid PEP-8. 26 | 27 | show-source = True 28 | ignore = E123,E125,E203,E402,E501,E741,F401,F811,F841,W503 29 | max-line-length = 160 30 | builtins = _ 31 | exclude = .git,.tox,tests/unit/compat/ 32 | --------------------------------------------------------------------------------