diff --git a/.ansible-lint b/.ansible-lint index 218f356..a7cb38d 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -24,16 +24,22 @@ mock_modules: - cisco.catalystwan.active_sessions_info - cisco.catalystwan.administration_settings - cisco.catalystwan.alarms + - cisco.catalystwan.cli_templates + - cisco.catalystwan.device_templates - cisco.catalystwan.devices_certificates - cisco.catalystwan.devices_controllers - cisco.catalystwan.devices_info - cisco.catalystwan.devices_wan_edges + - cisco.catalystwan.device_templates_recovery + - cisco.catalystwan.feature_templates + - cisco.catalystwan.feature_templates_info - cisco.catalystwan.health_checks - cisco.catalystwan.server_info - cisco.catalystwan.software_repository - cisco.catalystwan.software_repository_info - cisco.catalystwan.software_upgrade - cisco.catalystwan.software_upgrade_info + - cisco.catalystwan.device_templates_info - cisco.catalystwan.users - cisco.catalystwan.vmanage_mode - cisco.catalystwan.wait_for_api_server diff --git a/.gitignore b/.gitignore index 6eb99a4..7abcbf0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ poetry.lock .vscode* .venv* +run* .dev_dir/playground.yml .dev_dir/dev_vars.yml .dev_dir/ansible_catalystwan_module.log @@ -16,3 +17,7 @@ playbooks/tests/configuration_file_dev_vars.yml playbooks/tests/ansible_catalystwan.log playbooks/tests/ansible_catalystwan_module.log playbooks/tests/catalystwan.log +playbooks/tests/payload* +playbooks/tests/response* +playbooks/tests/backup +playbooks/tests/templates diff --git a/README.md b/README.md index c874e49..401d9fd 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,16 @@ # Ansible Collection - cisco.catalystwan -Initial repository for Ansible Collection using catalystwan library. +## Overview + +Reusable Ansible modules and roles that will help to automate Cisco +SD-WAN management (post bringup operations, day0, day1). + +All modules are based on [catalystwan](https://github.com/CiscoDevNet/catalystwan). -***NOTE: this repository is still in pre-release dev version** +Collection available on Ansible Galaxy: [cisco.catalystwan](https://galaxy.ansible.com/ui/repo/published/cisco/catalystwan/) ## Table of Contents -- [Overview](#overview) - [Roadmap](#roadmap) - [Requirements](#requirements) - [Installing this collection](#installing-this-collection) @@ -17,18 +21,6 @@ Initial repository for Ansible Collection using catalystwan library. --- -## Overview - -Reusable Ansible modules and roles that will help to automate Cisco -SD-WAN management (post bringup operations, day0, day1). - -All modules are based on [catalystwan](https://github.com/CiscoDevNet/catalystwan). Current installation available -via local Ansible Galaxy collection. - -Once finished, repository will be migrated to Cisco Open, and modules will be available via Ansible Galaxy. - ---- - ## Roadmap Support for the following workflows in vManage client and as Ansible modules: @@ -73,7 +65,7 @@ Currently development of the tool was set with: - Python = 3.10.0 - Ansible = 2.16.6 -- catalystwan = "^0.33.3" +- catalystwan = "^0.33.6post0" ## Installing this collection @@ -168,6 +160,14 @@ These playbooks offer initial config, onboarding and health checks. If you want to run example playbook, supply your variables in `.dev_dir/dev_vars.yml` and execute playbooks from `.dev_dir/` directory. +### Feature Templates + +Feature Templates operations (`add` and `delete`) are supported via `cisco.catalystwan.feature_templates` module. + +Available models are dependent on Catalystwan SDK, and they can be seen [here](https://github.com/cisco-open/cisco-catalyst-wan-sdk/blob/main/catalystwan/api/templates/models/supported.py). + +For more information about adding new models see [Feature Templates generation](./plugins/README.md#feature-templates). + --- ## Useful links and Getting Started diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 3d70633..53edbbc 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -51,3 +51,11 @@ Preferred way to setup environment for development: You can also refer to [Ansible modules dev guide](https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_general.html#verifying-your-module-code) to look for more convenient way of testing your code. + +### Dependencies in requirements.txt + +Dependencies defined for development are later used to generate `requirements.txt` file with command: + +```bash +poetry export --without-hashes --format=requirements.txt > requirements.txt +``` diff --git a/galaxy.yml b/galaxy.yml index 34efd9d..c0e6646 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,6 +1,6 @@ namespace: cisco name: catalystwan -version: 0.1.1 +version: 0.2.0 readme: README.md authors: - Arkadiusz Cichon diff --git a/playbooks/tests/test_backup_and_restore_running_config.yml b/playbooks/tests/test_backup_and_restore_running_config.yml new file mode 100644 index 0000000..267ab54 --- /dev/null +++ b/playbooks/tests/test_backup_and_restore_running_config.yml @@ -0,0 +1,76 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +# Helper playbooks to test modules and flows while developing them + +# Tested operations: + +# --- Backup & Restore --- # + +# 1. Backup running-config for all c8000V devices with default backup dir +# 2. Using backup files, create CLI templates for each Edge device +# 3. Attach backup templates to the Edge devices +# 4. Post-test - Set vManage mode for cEdge devices - in order to use previous templates + + +- name: Testing playbook to verify backup & restore operations + hosts: localhost + gather_facts: false + vars_files: + - configuration_file_dev_vars.yml + vars: + manager_authentication: &manager_authentication + url: "{{ (vmanage_instances | first).mgmt_public_ip }}" + username: "{{ (vmanage_instances | first).admin_username }}" + password: "{{ (vmanage_instances | first).admin_password }}" + tasks: + - name: 1. Backup running-config for all c8000V devices with default backup dir (in CWD) + cisco.catalystwan.devices_info: + backup: true + filters: + personality: "vedge" + manager_credentials: + <<: *manager_authentication + register: backup_info + + - name: 2. Using backup files, create CLI templates for each Edge device + cisco.catalystwan.cli_templates: + state: present + template_name: "backup-template-{{ device_item.filename }}" + template_description: "Template for {{ device_item.hostname }} created from backup file." + config_file: "{{ device_item.backup_path }}" + device_model: vedge-C8000V + manager_credentials: + <<: *manager_authentication + loop: "{{ backup_info.backup_paths }}" + loop_control: + loop_var: device_item + when: backup_info.backup_paths | length > 0 + + - name: 3. Attach backup templates to the Edge devices + cisco.catalystwan.device_templates: + state: attached + template_name: "backup-template-{{ device_item.filename }}" + hostname: "{{ device_item.hostname }}" + manager_credentials: + <<: *manager_authentication + loop: "{{ backup_info.backup_paths }}" + loop_control: + loop_var: device_item + when: backup_info.backup_paths | length > 0 + + - name: 4. Post-test - Set vManage mode for cEdge devices - in order to use previous templates + cisco.catalystwan.vmanage_mode: + state: present + hostnames: + - "{{ device_item.hostname }}" + manager_credentials: + <<: *manager_authentication + loop: "{{ backup_info.backup_paths }}" + loop_control: + loop_var: device_item + when: backup_info.backup_paths | length > 0 + + # Add task to remove all unused templates (not attached) diff --git a/playbooks/tests/test_device_templates.yml b/playbooks/tests/test_device_templates.yml new file mode 100644 index 0000000..04ece5e --- /dev/null +++ b/playbooks/tests/test_device_templates.yml @@ -0,0 +1,50 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +# Helper playbooks to test modules and flows while developing them + +# --- Device Templates --- # + + +- name: Testing playbook to verify cisco.catalystwan.device_templates module operations + hosts: localhost + gather_facts: false + vars_files: + - configuration_file_dev_vars.yml + vars: + manager_authentication: &manager_authentication + url: "{{ (vmanage_instances | first).mgmt_public_ip }}" + username: "{{ (vmanage_instances | first).admin_username }}" + password: "{{ (vmanage_instances | first).admin_password }}" + tasks: + - name: 1. Get all Non-Default Device Templates available + cisco.catalystwan.device_templates_info: + filters: + factory_default: false + manager_credentials: + <<: *manager_authentication + register: device_templates + + - name: 2. Delete selected Device Template from vManage + cisco.catalystwan.device_templates: + state: absent + template_name: "vc8000-device-template" + manager_credentials: + <<: *manager_authentication + + - name: 3. Create example Device Template with default templates + cisco.catalystwan.device_templates: + state: present + template_name: "vc8000-device-template" + template_description: "vc8000-device-template" + device_type: vedge-C8000V + device_role: sdwan-edge + general_templates: + - name: "Factory_Default_Cisco_BFD_Template" + subtemplates: "Factory_Default_Cisco_Logging_Template" + - name: "Factory_Default_Cisco_OMP_ipv46_Template" + - name: "Factory_Default_Cisco_Security_Template" + manager_credentials: + <<: *manager_authentication diff --git a/playbooks/tests/test_device_templates_info.yml b/playbooks/tests/test_device_templates_info.yml new file mode 100644 index 0000000..dff01bd --- /dev/null +++ b/playbooks/tests/test_device_templates_info.yml @@ -0,0 +1,41 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +# Helper playbooks to test modules and flows while developing them + +# --- Device Templates Info --- # + + +- name: Testing playbook to verify cisco.catalystwan.device_templates_info module operations + hosts: localhost + gather_facts: false + vars_files: + - configuration_file_dev_vars.yml + vars: + manager_authentication: &manager_authentication + url: "{{ (vmanage_instances | first).mgmt_public_ip }}" + username: "{{ (vmanage_instances | first).admin_username }}" + password: "{{ (vmanage_instances | first).admin_password }}" + tasks: + - name: 1. Get all Non-Default Device Templates available + cisco.catalystwan.device_templates_info: + filters: + factory_default: false + manager_credentials: + <<: *manager_authentication + register: device_templates + + - name: 2. Debug Templates Info + ansible.builtin.debug: + msg: "{{ device_templates }}" + + - name: 3. Backup all Non-Default Device Templates available + cisco.catalystwan.device_templates_info: + filters: + factory_default: false + backup: true + manager_credentials: + <<: *manager_authentication + register: device_templates diff --git a/playbooks/tests/test_feature_templates.yml b/playbooks/tests/test_feature_templates.yml new file mode 100644 index 0000000..40a340b --- /dev/null +++ b/playbooks/tests/test_feature_templates.yml @@ -0,0 +1,1050 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +# Helper playbooks to test modules and flows while developing them + +# Tested operations: + +# --- Feature Templates creation --- # + + +- name: Testing playbook to verify cisco.catalystwan.feature_template module operations + hosts: localhost + gather_facts: false + vars_files: + - configuration_file_dev_vars.yml + vars: + manager_authentication: &manager_authentication + url: "{{ (vmanage_instances | first).mgmt_public_ip }}" + username: "{{ (vmanage_instances | first).admin_username }}" + password: "{{ (vmanage_instances | first).admin_password }}" + tasks: + - name: 1. Get all Non-Default Feature Templates available + cisco.catalystwan.feature_templates_info: + filters: + factory_default: false + devices_attached: 0 + manager_credentials: + <<: *manager_authentication + register: feature_templates + + - name: 2. Delete all Non-Default Feature templates + cisco.catalystwan.feature_templates: + state: absent + template_name: "{{ template.name }}" + manager_credentials: + <<: *manager_authentication + loop: "{{ feature_templates.templates_info | default([], true) }}" + loop_control: + loop_var: template + label: "template: {{ template.name }}" + + # vedge-C8000V templates + + - name: 2. Create Comprehensive AAA Template with TACACS+ and RADIUS + cisco.catalystwan.feature_templates: + state: present + template_name: "ComprehensiveAAATemplate" + template_description: "AAA Template with both TACACS+ and RADIUS servers" + device_models: + - vedge-C8000V + cisco_aaa: + user: + - name: "local_admin" + password: "admin_password" + secret: "admin_secret" + privilege: "15" + pubkey_chain: + - key_string: "AAAAB3NzaC1yc2EAAAADAQABAAABAQC3myRj5L6ZFLdRnOEZdUd+4Qq0XPLW9RfO6qD7DJ2t4ZzLh6Oz+IUJg8d8bJDfxO9zGKs5uUQ9f2H5yTGX5G8Z5kKp8QDp1MkDVqwGJ4UM7JqH8s8kD7xcl8SyPc5TjzK4s4W+8LPNOPXmIKtHh1Qlvkp5N7w3M/Rm5ZVX5/3+Hk8Ib5syigQQd/5u5xJj9k3i2x3m3LZ7v5e7YlCpRdCQGf6ZCwvbVQHdJp5nlU0HxJbqjOTL4IcDj09G3Dq2C5JnohKJb7E7HVCUl7F5vYpC/4iNjges65GgdzaFJsT9qA8CgxyF+7J3PpLk5qPAQDT5OjArJj4x9Bw3j3lZdH example@example.com" # noqa yaml[line-length] + key_type: "ssh-rsa" + authentication_group: true + accounting_group: true + radius: + - group_name: "radius_group1" + vpn: "1" + source_interface: "GigabitEthernet0/0" + server: + - address: "192.0.2.1" + auth_port: 1812 + acct_port: 1813 + timeout: 5 + retransmit: 3 + key: "secure_radius_server_key" + secret_key: "radius_secret" + key_enum: "key_enum_value" + key_type: "key_type_value" + domain_stripping: "right-to-left" + port: 1234 + authentication_type: any + server_auth_order: "local radius_group1 tacacs_group1" + server_key_password: "secure_server_key_password" + cts_authorization_list: "example_element" + radius_trustsec_group: "radius_group1" + radius_client: + - ip: 2.2.2.2 + vpn: + - name: example_radius_client + server_key: secure_radius_client_key + accounting_rules: + - rule_id: 0 + method: network + level: "1" + group: "radius_group1,tacacs_group1" + start_stop: false + authorization_console: true + authorization_config_commands: true + authorization_rules: + - rule_id: 111 + method: commands + group: "radius_group1,tacacs_group1" + authenticated: true + tacacs: + - group_name: "tacacs_group1" + vpn: 2 + source_interface: "GigabitEthernet0/1" + server: + - address: "192.0.2.2" + port: 49 + timeout: 10 + key: "tacacs_key" + secret_key: "tacacs_secret" + key_enum: "key_enum_value" + manager_credentials: + <<: *manager_authentication + + - name: 3. Create Cisco Banner Feature Template + cisco.catalystwan.feature_templates: + state: present + template_name: "CiscoBannerConfigTemplate" + template_description: "Banner configuration for login and MOTD" + device_models: + - "vedge-C8000V" + cisco_banner: + login_banner: | + **************************************************************** + * Unauthorized access to this device is prohibited. * + * You must have explicit permission to access or configure this * + * device. All activities performed on this device are logged and * + * violations of this policy may result in disciplinary action, * + * and may be reported to law enforcement. There is no right to * + * privacy on this device. Use of this system constitutes consent * + * to monitoring for these purposes. * + **************************************************************** + motd_banner: | + **************************************************************** + * Welcome to Company XYZ Network! * + * All connections are monitored and recorded for audit purposes. * + * Disconnect IMMEDIATELY if you are not an authorized user! * + **************************************************************** + manager_credentials: + <<: *manager_authentication + + - name: 4. Create Cisco BFD Feature Template + cisco.catalystwan.feature_templates: + state: present + template_name: "CiscoBFDFeatureTemplate" + template_description: "Comprehensive BFD configuration" + device_models: + - "vedge-C8000V" + cisco_bfd: + multiplier: "3" + poll_interval: "500" + default_dscp: "46" + color: + - color: "mpls" + hello_interval: "200" + multiplier: "4" + pmtu_discovery: true + dscp: "46" + - color: "biz-internet" + hello_interval: "300" + multiplier: "5" + pmtu_discovery: false + dscp: "34" + - color: "private1" + hello_interval: "250" + multiplier: "3" + pmtu_discovery: true + dscp: "26" + - color: "custom3" + hello_interval: "350" + multiplier: "6" + pmtu_discovery: true + dscp: "18" + manager_credentials: + <<: *manager_authentication + + - name: 5. Configure Cisco Logging Feature Template + cisco.catalystwan.feature_templates: + state: present + template_name: "CiscoLoggingFeatureTemplate" + template_description: "Comprehensive Logging Configuration" + device_models: + - "vedge-C8000V" + cisco_logging: + enable: true + size: "20" + rotate: "5" + tls_profile: + - profile: "default_tls_profile" + version: "TLSv1.2" + auth_type: "Server" + ciphersuite_list: + - "ECDHE-ECDSA-AES256-GCM-SHA384" + - "ECDHE-RSA-AES256-GCM-SHA384" + - profile: "secure_tls_profile" + version: "TLSv1.2" + auth_type: "Mutual" + ciphersuite_list: + - "ECDHE-ECDSA-CHACHA20-POLY1305" + - "ECDHE-RSA-CHACHA20-POLY1305" + server: + - name: "1.1.1.1" + vpn: "10" + source_interface: "GigabitEthernet0/0" + priority: "debugging" + enable_tls: true + custom_profile: true + profile: "default_tls_profile" + - name: "log_server_2" + vpn: "20" + source_interface: "GigabitEthernet0/1" + priority: "error" + enable_tls: false + ipv6_server: + - name: "ipv6_log_server_1" + vpn: "10" + source_interface: "GigabitEthernet0/2" + priority: "critical" + enable_tls: true + custom_profile: true + profile: "secure_tls_profile" + - name: "ipv6_log_server_2" + vpn: "30" + source_interface: "GigabitEthernet0/3" + priority: "emergency" + enable_tls: false + manager_credentials: + <<: *manager_authentication + + - name: 6. Configure Cisco NTP Feature Template + cisco.catalystwan.feature_templates: + state: present + template_name: "CiscoNTPFeatureTemplate" + template_description: "Comprehensive NTP Configuration" + device_models: + - "vedge-C8000V" + cisco_ntp: + server: + - name: "0.pool.ntp.org" + key: "1" + vpn: "10" + version: "4" + source_interface: "GigabitEthernet0/0" + prefer: true + - name: "1.pool.ntp.org" + key: "2" + vpn: "20" + version: "4" + source_interface: "GigabitEthernet0/1" + prefer: false + authentication: + - number: 1 + md5: "md5key1" + - number: 2 + md5: "md5key2" + trusted: + - 1 + - 2 + enable: true + stratum: "2" + source: "Loopback0" + manager_credentials: + <<: *manager_authentication + + - name: 7. Configure Cisco OMP Feature Template + cisco.catalystwan.feature_templates: + state: present + template_name: "CiscoOMPFeatureTemplate" + template_description: "Comprehensive OMP Configuration" + device_models: + - "vsmart" + cisco_omp: + graceful_restart: true + overlay_as: "65000" + send_path_limit: "10" + ecmp_limit: "8" + shutdown: false + omp_admin_distance_ipv4: "110" + omp_admin_distance_ipv6: "115" + advertisement_interval: "30" + graceful_restart_timer: "120" + eor_timer: "300" + holdtime: "180" + advertise: + - protocol: "bgp" + route: "external" + - protocol: "ospf" + - protocol: "connected" + - protocol: "static" + - protocol: "eigrp" + - protocol: "lisp" + ipv6_advertise: + - protocol: "bgp" + - protocol: "ospf" + - protocol: "connected" + - protocol: "static" + ignore_region_path_length: true + transport_gateway: "prefer" + site_types: + - "type-1" + - "type-2" + - "cloud" + - "branch" + - "spoke" + auto_translate: true + manager_credentials: + <<: *manager_authentication + + - name: 8. Configure Cisco OSPF Feature Template + cisco.catalystwan.feature_templates: + state: present + template_name: "CiscoOSPFeatureTemplate" + template_description: "Comprehensive OSPF Configuration" + device_models: + - "vedge-C8000V" + cisco_ospf: + router_id: "1.1.1.1" + reference_bandwidth: "10000" + rfc1583: false + originate: true + always: true + metric: "10" + metric_type: "type1" + external: "20" + inter_area: "30" + intra_area: "40" + delay: "5" + initial_hold: "10" + max_hold: "40" + redistribute: + - protocol: "static" + route_policy: "static_policy" + dia: true + - protocol: "bgp" + route_policy: "bgp_to_ospf_policy" + dia: false + router_lsa: + - ad_type: "administrative" + time: 10 + route_policy: + - direction: "in" + pol_name: "ospf_in_policy" + area: + - a_num: 0 + stub: false + nssa: true + interface: + - name: "GigabitEthernet0/0" + hello_interval: "10" + dead_interval: "40" + retransmit_interval: "5" + cost: "1" + priority: "1" + network: "broadcast" + passive_interface: false + type: "simple" + message_digest_key: "1" + md5: "md5keystring" + range: + - address: "192.168.1.0/24" + cost: "100" + no_advertise: true + manager_credentials: + <<: *manager_authentication + + - name: 9. Configure Secure Internet Gateway feature template + cisco.catalystwan.feature_templates: + state: present + template_name: "CiscoSecureInternetGatewayFeatureTemplate" + template_description: "Comprehensive CiscoSecureInternetGateway Configuration" + device_models: + - "vedge-C8000V" + cisco_secure_internet_gateway: + vpn_id: 10 + child_org_id: "example_org" + interface: + - if_name: "GigabitEthernet0/0" + auto: true + shutdown: false + description: "Main interface for SIG" + unnumbered: false + address: "192.168.1.1/24" + tunnel_source: "192.168.1.1" + tunnel_source_interface: "Loopback0" + tunnel_route_via: "192.168.2.1" + tunnel_destination: "203.0.113.1" + application: "sig" + tunnel_set: "secure-internet-gateway-umbrella" + tunnel_dc_preference: "primary-dc" + tcp_mss_adjust: "1400" + mtu: 1400 + dpd_interval: "30" + dpd_retries: "3" + ike_version: 2 + pre_shared_secret: "MyPreSharedSecret" + ike_rekey_interval: "3600" + ike_ciphersuite: "aes256-cbc-sha1" + ike_group: "14" + pre_shared_key_dynamic: false + ike_local_id: "local-id" + ike_remote_id: "remote-id" + ipsec_rekey_interval: "3600" + ipsec_replay_window: "32" + ipsec_ciphersuite: "aes256-gcm" + perfect_forward_secrecy: "group-14" + tracker: true + track_enable: true + service: + - svc_type: "sig" + interface_pair: + - active_interface: "GigabitEthernet0/0" + active_interface_weight: 10 + backup_interface: "GigabitEthernet0/1" + backup_interface_weight: 5 + auth_required: "yes" + xff_forward_enabled: "yes" + ofw_enabled: "no" + ips_control: "yes" + caution_enabled: "no" + primary_data_center: "Auto" + secondary_data_center: "Auto" + ip: "yes" + idle_time: "30" + display_time_unit: "MINUTE" + ip_enforced_for_known_browsers: "yes" + refresh_time: "5" + refresh_time_unit: "MINUTE" + enabled: "yes" + block_internet_until_accepted: "no" + force_ssl_inspection: "yes" + timeout: "60" + data_center_primary: "Auto" + data_center_secondary: "Auto" + tracker_src_ip: "192.0.2.1" + tracker: + - name: "health-check-tracker" + endpoint_api_url: "https://api.example.com/health" + threshold: "5" + interval: "60" + multiplier: "2" + tracker_type: "SIG" + manager_credentials: + <<: *manager_authentication + + - name: 10. Configure Cisco SNMP feature template + cisco.catalystwan.feature_templates: + state: present + template_name: "CiscoSNMPFeatureTemplate" + template_description: "Comprehensive Cisco SNMP Configuration" + cisco_snmp: + shutdown: false + contact: "SNMP Admin" + location: "Data Center A" + view: + - name: "SystemView" + oid: + - id: "1.3.6.1.2.1.1" + exclude: false + - id: "1.3.6.1.2.1.2" + exclude: true + - name: "AllView" + oid: + - id: "1.3.6.1" + exclude: false + community: + - name: "public" + view: "SystemView" + authorization: "read-only" + - name: "private" + view: "AllView" + authorization: "read-only" + group: + - name: "v3group" + security_level: "auth-priv" + view: "AllView" + user: + - name: "snmpuser" + auth: "md5" + auth_password: "authpass" + priv: "aes-cfb-128" + priv_password: "privpass" + group: "v3group" + target: + - vpn_id: 10 + ip: "192.0.2.50" + port: 162 + community_name: "public" + user: "snmpuser" + source_interface: "GigabitEthernet0/0" + manager_credentials: + <<: *manager_authentication + + - name: 11. Create Comprehensive Cisco System Template + cisco.catalystwan.feature_templates: + state: present + template_name: "ComprehensiveCiscoSystemTemplate" + template_description: "Cisco System template" + device_models: + - "vedge-C8000V" + cisco_system: + timezone: "UTC" + description: "Example desc" + hostname: + name: "sdwan-hostname" + location: "Data Center A" + latitude: "37.7749" + longitude: "-122.4194" + range: "10" + enable_fencing: true + mobile_number: + - number: "+12345678901" + - number: "+10987654321" + enable_sms: true + device_groups: + - "group1" + - "group2" + controller_group_list: + - 1 + - 3 + system_ip: + name: "192.0.2.1" + overlay_id: "1" + site_id: 1001 + site_type: + - "branch" + - "spoke" + port_offset: "1000" + port_hop: true + control_session_pps: "500" + track_transport: true + track_interface_tag: "1" + console_baud_rate: "9600" + max_omp_sessions: "50" + multi_tenant: false + track_default_gateway: false + admin_tech_on_failure: true + enable_tunnel: true + idle_timeout: "300" + on_demand_idle_timeout_min: "60" + tracker: + - name: "tracker1" + endpoint_ip: "203.0.113.1" + endpoint_ip_transport_port: "8080" + protocol: "tcp" + port: "443" + elements: + - "element1, element2" + boolean: "and" + threshold: "10" + interval: "30" + multiplier: "3" + type: "static-route" + object_track: + - object_number: 10 + interface: 'GigabitEthernet0/0/0' + sig: '100' + ip: '192.0.2.1' + mask: '255.255.255.0' + vpn: 1 + object: + - number: 101 + boolean: 'and' + - object_number: 20 + interface: 'GigabitEthernet0/0/0' + sig: '100' + ip: '192.0.2.1' + mask: '255.255.255.0' + vpn: 1 + object: + - number: 101 + boolean: 'and' + - object_number: 30 + interface: 'GigabitEthernet0/0/1' + sig: '200' + ip: '198.51.100.1' + mask: '255.255.255.0' + vpn: 2 + object: + - number: 201 + boolean: 'or' + preference: + - 1 + preference_auto: true + epfr: "conservative" + vrf: + - vrf_id: 1 + gateway_preference: + - 4 + - 5 + - vrf_id: 2 + gateway_preference: + - 12 + - 13 + enable_management_region: true + migration_bgp_community: 65535 + enable_mrf_migration: enabled + transport_gateway: true + affinity_group_number: 1 + affinity_per_vrf: + - affinity_group_number: 1 + vrf_range: "22" + role: "edge-router" + # secondary_region: 55 + # region_id: 44 + manager_credentials: + <<: *manager_authentication + + - name: 12. Create Comprehensive Cisco VPN Interface Template + cisco.catalystwan.feature_templates: + state: present + template_name: "ComprehensiveCiscoVPNInterfaceTemplate" + template_description: "Cisco VPN Interface template" + device_models: + - "vedge-C8000V" + cisco_vpn_interface: + if_name: "GigabitEthernet0/0" + interface_description: "WAN interface" + poe: true + ipv4_address: "192.0.2.1/24" + secondary_ipv4_address: + - address: "192.0.2.2/24" + - address: "192.0.2.3/24" + dhcp_ipv4_client: false + dhcp_distance: "1" + ipv6_address: "2001:db8::1/64" + dhcp_ipv6_client: true + secondary_ipv6_address: + - address: "2001:db8::2/64" + - address: "2001:db8::3/64" + access_list_ipv4: + - direction: "in" + acl_name: "ACL-INBOUND" + - direction: "out" + acl_name: "ACL-OUTBOUND" + dhcp_helper: + - "192.0.2.254" + dhcp_helper_v6: + - address: "2001:db8::1" + vpn: "0" + tracker: + - "Tracker1" + - "Tracker2" + auto_bandwidth_detect: true + iperf_server: "192.0.2.100" + nat: true + nat_choice: "Interface" + udp_timeout: "30" + tcp_timeout: "60" + nat_range_start: "192.0.2.100" + nat_range_end: "192.0.2.200" + overload: true + loopback_interface: "Loopback0" + prefix_length: "24" + enable: true + nat64: false + nat66: false + static_nat66: + - source_prefix: "2001:db8:1234::/64" + translated_source_prefix: "2001:db8:5678::/64" + source_vpn_id: 10 + static: + - source_ip: "192.0.2.1" + translate_ip: "203.0.113.1" + static_nat_direction: "inside" + source_vpn: 10 + static_port_forward: + - source_ip: "192.0.2.2" + translate_ip: "203.0.113.2" + static_nat_direction: "outside" + source_port: 8080 + translate_port: 9090 + proto: "tcp" + source_vpn: 10 + enable_core_region: true + core_region: "core" + secondary_region: "secondary-only" + tloc_encapsulation: + - encap: "ipsec" + preference: "100" + weight: 1 + border: true + per_tunnel_qos: true + per_tunnel_qos_aggregator: true + mode: "hub" + tunnels_bandwidth: "1000" + group: + - "1" + - "2" + value: "mpls" + max_control_connections: "5" + control_connections: true + vbond_as_stun_server: true + exclude_controller_group_list: + - "3" + - "4" + vmanage_connection_preference: "100" + port_hop: true + restrict: false + dst_ip: "198.51.100.14" + carrier: "carrier1" + nat_refresh_interval: "30" + hello_interval: "10" + hello_tolerance: "30" + bind: "GigabitEthernet0/0" + last_resort_circuit: false + low_bandwidth_link: false + tunnel_tcp_mss_adjust: "1360" + clear_dont_fragment: true + propagate_sgt: false + network_broadcast: true + all: false + bgp: true + dhcp: false + dns: true + icmp: true + sshd: true + netconf: false + ntp: true + ospf: false + stun: false + snmp: true + https: true + media_type: "rj45" + intrf_mtu: "1500" + mtu: "1400" + tcp_mss_adjust: "1360" + tloc_extension: "100" + load_interval: "300" + src_ip: "198.51.100.1" + xconnect: "10" + mac_address: "00:0C:29:4B:55:3A" + speed: "1000" + duplex: "full" + shutdown: false + arp_timeout: "1200" + autonegotiate: true + ip_directed_broadcast: false + icmp_redirect_disable: true + qos_adaptive: true + period: "60" + bandwidth_down: "10000" + dmin: "5000" + dmax: "15000" + bandwidth_up: "5000" + umin: "2500" + umax: "7500" + shaping_rate: "5000" + qos_map: "default_qos_map" + qos_map_vpn: "vpn_qos_map" + service_provider: "ISP1" + bandwidth_upstream: "5000" + bandwidth_downstream: "10000" + block_non_source_ip: true + rule_name: "rewrite_rule_1" + access_list_ipv6: + - direction: "in" + acl_name: "ipv6_acl_1" + ip: + - addr: "192.0.2.1" + mac: "00:0C:29:4B:55:3A" + vrrp: + - grp_id: 1 + priority: 110 + timer: 100 + track_omp: true + track_prefix_list: "TRACKING_LIST" + address: "192.0.2.254" + ipv4_secondary: + - address: "192.0.2.253" + tloc_change_pref: true + value: 20 + tracking_object: + - name: 10 + track_action: "Decrement" + decrement: 20 + ipv6_vrrp: + - grp_id: 1 + priority: 110 + timer: 100 + track_omp: true + track_prefix_list: "TRACKING_LIST_IPV6" + ipv6: + - ipv6_link_local: "FE80::1" + prefix: "2001:db8::/64" + enable_sgt_propagation: true + security_group_tag: "0000" + trusted: true + enable_sgt_authorization_and_forwarding: true + enable_sgt_enforcement: true + enforcement_sgt: "010001" + manager_credentials: + <<: *manager_authentication + + - name: 13. Create Comprehensive Cisco VPN Template + cisco.catalystwan.feature_templates: + state: present + template_name: "ComprehensiveCiscoVPNTemplate" + template_description: "Cisco VPN template" + device_models: + - "vedge-C8000V" + cisco_vpn: + vpn_id: 10 + vpn_name: "CorporateVPN" + tenant_vpn_id: 200 + org_name: "ACME_Corporation" + omp_admin_distance_ipv4: 5 + omp_admin_distance_ipv6: 5 + dns: + - dns_addr: "8.8.8.8" + role: "primary" + - dns_addr: "8.8.4.4" + role: "secondary" + dns_ipv6: + - dns_addr: "2001:4860:4860::8888" + role: "primary" + - dns_addr: "2001:4860:4860::8844" + role: "secondary" + layer4: true + host: + - hostname: "server1.example.com" + ip: + - "192.168.1.10" + service: + - svc_type: "FW" + address: + - "192.168.2.10" + interface: "GigabitEthernet0/0" + track_enable: true + service_route: + - prefix: "192.168.3.0/24" + vpn: 10 + service: "sig" + route_v4: + - prefix: "192.168.1.0/24" + next_hop: + - address: "192.168.1.1" + distance: 10 + next_hop_with_track: + - address: "192.168.1.2" + distance: 20 + tracker: "Track1" + route_interface: + interface_name: "GigabitEthernet0/0" + interface_next_hop: + - address: "2001:db8:abcd:0012::1" + distance: 1 + null0: false + distance: 1 + vpn: 10 + dhcp: false + route_v6: + - prefix: "2001:db8:abcd:0012::/64" + next_hop: + - address: "2001:db8:abcd:0012::1" + distance: 10 + null0: false + vpn: 10 + nat: "NAT64" + gre_route: + - prefix: "10.0.0.0/8" + vpn: 20 + interface: + - "Tunnel0" + ipsec_route: + - prefix: "172.16.0.0/12" + vpn: 30 + interface: + - "Tunnel1" + advertise: + - protocol: bgp + route_policy: "BGP-Export-Policy" + protocol_sub_type: + - external + prefix_list: + - prefix_entry: "192.168.50.0/24" + aggregate_only: false + region: core + - prefix_entry: "192.168.60.0/24" + aggregate_only: true + region: access + ipv6_advertise: + - protocol: bgp + route_policy: "BGP-IPv6-Export-Policy" + protocol_sub_type: + - external + prefix_list: + - prefix_entry: "2001:db8:abcd:0012::/64" + aggregate_only: false + region: core + - prefix_entry: "2001:db8:abcd:0034::/64" + aggregate_only: true + region: access + pool: + - name: "NAT64Pool1" + start_address: "203.0.113.1" + end_address: "203.0.113.100" + overload: true + leak_from_global: true + leak_from_global_protocol: static + leak_to_global: false + natpool: + - name: 101 + prefix_length: 24 + range_start: "192.0.2.1" + range_end: "192.0.2.100" + overload: 'true' + direction: inside + tracker_id: 1 + static: + - pool_name: 101 + source_ip: "198.51.100.5" + translate_ip: "203.0.113.5" + static_nat_direction: inside + tracker_id: 2 + subnet_static: + - source_ip_subnet: "198.51.100.0/24" + translate_ip_subnet: "203.0.113.0/24" + prefix_length: 24 + static_nat_direction: inside + port_forward: + - pool_name: 101 + source_port: 8080 + translate_port: 80 + source_ip: "198.51.100.5" + translate_ip: "203.0.113.5" + proto: tcp + route_import: + - protocol: bgp + protocol_sub_type: ['external'] + route_policy: 'import-bgp-routes' + redistribute: + - protocol: ospf + route_policy: 'ospf-to-bgp' + route_import_from: + - source_vpn: 10 + protocol: static + protocol_sub_type: + - external + route_policy: 'import-static-from-vpn10' + redistribute: + - protocol: eigrp + route_policy: 'eigrp-to-vpn10' + route_export: + - protocol: bgp + protocol_sub_type: + - external + route_policy: 'export-bgp-routes' + redistribute: + - protocol: bgp + route_policy: 'static-to-bgp' + manager_credentials: + <<: *manager_authentication + + - name: 14. Create Comprehensive OMP vSmart Template + cisco.catalystwan.feature_templates: + state: present + template_name: "OMPvSmartConfigTemplate" + template_description: "Apply OMP settings for vSmart controller" + device_models: "vsmart" + omp_vsmart: + graceful_restart: true + graceful_restart_timer: 120 + send_path_limit: 100 + send_backup_paths: true + shutdown: false + discard_rejected: false + eor_timer: 50 + holdtime: 300 + affinity_group_preference: true + advertisement_interval: 30 + tloc_color: true + manager_credentials: + <<: *manager_authentication + + - name: 15. Create Comprehensive Security vSmart Template + cisco.catalystwan.feature_templates: + state: present + template_name: "SecurityvSmartConfigTemplate" + template_description: "Apply Security settings for vSmart controller" + device_models: vsmart + security_vsmart: + protocol: dtls + tls_port: 120 + manager_credentials: + <<: *manager_authentication + + - name: 16. Create Comprehensive System vSmart Template + cisco.catalystwan.feature_templates: + state: present + template_name: "SystemvSmartConfigTemplate" + template_description: "Apply System settings for vSmart controller" + device_models: vsmart + device_specific_variables: + site_id: "side_id_variable" + host_name: "host_name_variable" + system_ip: "system_ip_variable" + system_vsmart: + host_name: device_specific_variable + site_id: device_specific_variable + system_ip: device_specific_variable + timezone: UTC + idle_timeout: 100 + admin_tech_on_failure: true + iptables_enable: true + track_default_gateway: true + dns_cache_timeout: 10 + track_transport: true + controller_group_id: 44 + control_session_pps: 999 + port_hop: true + port_offset: 5 + overlay_id: 44 + device_groups: "example1,example2" + latitude: "37" + longitude: "-122" + system_tunnel_mtu: 1024 + location: "Location" + dual_stack_ipv6: true + description: "Example description" + topology: + - "hub-and-spoke" + region_list_id: 12 + management_region: true + compatible: + - color_1: mpls + color_2: metro-ethernet + incompatible: + - color_1: biz-internet + color_2: public-internet + manager_credentials: + <<: *manager_authentication + + # Example of devices specific variables - this works in Feature Templates, need to check Device Templates + - name: Create Cisco Banner Feature Template + cisco.catalystwan.feature_templates: + state: present + template_name: "CiscoBannerConfigTemplateDSV" + template_description: "Banner configuration for login and MOTD with DSV" + device_specific_variables: + login_banner: "var_name_1" + motd_banner: "var_name_2" + device_models: + - "vedge-C8000V" + cisco_banner: + login_banner: device_specific_variable + motd_banner: device_specific_variable + manager_credentials: + <<: *manager_authentication diff --git a/playbooks/tests/test_module_device_templates_recovery.yml b/playbooks/tests/test_module_device_templates_recovery.yml new file mode 100644 index 0000000..573a3a9 --- /dev/null +++ b/playbooks/tests/test_module_device_templates_recovery.yml @@ -0,0 +1,73 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +# Helper playbooks to test modules and flows while developing them + +# Tested operations: + +- name: Testing playbook to verify cisco.catalystwan.device_templates_recovery module operations + hosts: localhost + gather_facts: false + vars_files: + - configuration_file_dev_vars.yml + vars: + manager_authentication: &manager_authentication + url: "{{ (vmanage_instances | first).mgmt_public_ip }}" + username: "{{ (vmanage_instances | first).admin_username }}" + password: "{{ (vmanage_instances | first).admin_password }}" + tasks: + - name: 1. Perform backup of all non factory default Device Templates + cisco.catalystwan.device_templates_recovery: + mode: backup + backup_dir_path: "/Users/acichon/Work/cisco-open/ansible-collection-catalystwan/templates_export" + manager_credentials: + <<: *manager_authentication + + - name: 2. Get all Device Templates that are not attached to any device + cisco.catalystwan.device_templates_info: + filters: + devices_attached: 0 + factory_default: false + manager_credentials: + <<: *manager_authentication + register: device_templates + + - name: 3. Delete selected Device Templates from vManage + cisco.catalystwan.device_templates: + state: absent + template_name: "{{ device_template.name }}" + manager_credentials: + <<: *manager_authentication + loop: "{{ device_templates.templates_info | default([], True) }}" + loop_control: + loop_var: device_template + when: device_templates.templates_info | length > 0 + + - name: 4. Get all Non-Default Feature Templates available + cisco.catalystwan.feature_templates_info: + filters: + factory_default: false + devices_attached: 0 + manager_credentials: + <<: *manager_authentication + register: feature_templates + + - name: 5. Delete all Non-Default Feature templates + cisco.catalystwan.feature_templates: + state: absent + template_name: "{{ template.name }}" + manager_credentials: + <<: *manager_authentication + loop: "{{ feature_templates.templates_info | default([], true) }}" + loop_control: + loop_var: template + label: "template: {{ template.name }}" + + - name: 6. Restore Templates from backup directory + cisco.catalystwan.device_templates_recovery: + mode: restore + backup_dir_path: "/Users/acichon/Work/cisco-open/ansible-collection-catalystwan/templates_export" + manager_credentials: + <<: *manager_authentication diff --git a/playbooks/tests/test_module_devices_info.yml b/playbooks/tests/test_module_devices_info.yml index e4cd100..cdf25bb 100644 --- a/playbooks/tests/test_module_devices_info.yml +++ b/playbooks/tests/test_module_devices_info.yml @@ -16,17 +16,33 @@ gather_facts: false vars_files: - configuration_file_dev_vars.yml + vars: + manager_authentication: &manager_authentication + url: "{{ (vmanage_instances | first).mgmt_public_ip }}" + username: "{{ (vmanage_instances | first).admin_username }}" + password: "{{ (vmanage_instances | first).admin_password }}" tasks: - name: 1. Get list of Edge devices cisco.catalystwan.devices_info: device_category: vedges - manager_authentication: - url: "{{ (vmanage_instances | first).mgmt_public_ip }}" - username: "{{ (vmanage_instances | first).admin_username }}" - password: "{{ (vmanage_instances | first).admin_password }}" + manager_credentials: + <<: *manager_authentication register: edge_devices - - name: 2. Check if all controller devices are discoverable via system ip + - name: 2. Backup running-config from vManage with default backup dir (in CWD) + cisco.catalystwan.devices_info: + backup: true + manager_credentials: + <<: *manager_authentication + + - name: 3. Backup running-config from vManage to specified directory + cisco.catalystwan.devices_info: + backup: true + backup_dir_path: "/tmp/backups" + manager_credentials: + <<: *manager_authentication + + - name: 4. Check if all controller devices are discoverable via system ip cisco.catalystwan.devices_info: device_category: controllers filters: diff --git a/playbooks/tests/test_templates_attachment.yml b/playbooks/tests/test_templates_attachment.yml new file mode 100644 index 0000000..1083a56 --- /dev/null +++ b/playbooks/tests/test_templates_attachment.yml @@ -0,0 +1,258 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +# --- Device Templates attachment - created from Feature Templates--- # + +# Helper playbooks to test modules and flows while developing them + +# Tested operations: + +# 1. Get all Device Templates that are not attached to any device +# 2. Delete selected Device Templates from vManage +# 3. Backup running-config from devices, store in default backup dir (in CWD) +# 4. Using backup files, create CLI templates for each device available +# 5. Get all Non-Default Feature Templates available +# 6. Delete all Non-Default Feature templates +# 7. Create AAA Template for vSmart devices +# 8. Create System Template for vSmart devices +# 9. Create VPN template for vSmart devices - VPN 0 +# 10. Create VPN template for vSmart devices - VPN 512 +# 11. Create VPN Interface template for vSmart devices - VPN 0 +# 12. Create VPN Interface template for vSmart devices - VPN 512 +# 13. Create example Device Template for vSmart +# 14. Attach example Device Template for vSmart + + +- name: Testing playbook to verify cisco.catalystwan.device_templates module operations + hosts: localhost + gather_facts: false + vars_files: + - configuration_file_dev_vars.yml + vars: + manager_authentication: &manager_authentication + url: "{{ (vmanage_instances | first).mgmt_public_ip }}" + username: "{{ (vmanage_instances | first).admin_username }}" + password: "{{ (vmanage_instances | first).admin_password }}" + tasks: + - name: 1. Get all Device Templates that are not attached to any device + cisco.catalystwan.device_templates_info: + filters: + devices_attached: 0 + factory_default: false + manager_credentials: + <<: *manager_authentication + register: device_templates + + - name: 2. Delete selected Device Templates from vManage + cisco.catalystwan.device_templates: + state: absent + template_name: "{{ device_template.name }}" + manager_credentials: + <<: *manager_authentication + loop: "{{ device_templates.templates_info | default([], True) }}" + loop_control: + loop_var: device_template + when: device_templates.templates_info | length > 0 + + - name: 3. Backup running-config from devices, store in default backup dir (in CWD) + cisco.catalystwan.devices_info: + backup: true + manager_credentials: + <<: *manager_authentication + register: backup_info + + - name: 4. Using backup files, create CLI templates for each device available + cisco.catalystwan.cli_templates: + state: present + template_name: "backup-template-{{ device_item.filename }}" + template_description: "Template for {{ device_item.hostname }} created from backup file." + config_file: "{{ device_item.backup_path }}" + device_model: "{% if 'cedge' in device_item.hostname %}vedge-C8000V\ + {% elif 'vSmart' in device_item.hostname %}vsmart{% elif 'vManage' in device_item.hostname %}vmanage\ + {% elif 'vBond' in device_item.hostname %}vedge-cloud{% endif %}" + manager_credentials: + <<: *manager_authentication + loop: "{{ backup_info.backup_paths }}" + loop_control: + loop_var: device_item + when: backup_info.backup_paths | length > 0 + + - name: 5. Get all Non-Default Feature Templates available + cisco.catalystwan.feature_templates_info: + filters: + factory_default: false + devices_attached: 0 + manager_credentials: + <<: *manager_authentication + register: feature_templates + + - name: 6. Delete all Non-Default Feature templates + cisco.catalystwan.feature_templates: + state: absent + template_name: "{{ template.name }}" + manager_credentials: + <<: *manager_authentication + loop: "{{ feature_templates.templates_info | default([], true) }}" + loop_control: + loop_var: template + label: "template: {{ template.name }}" + + # Create now all Feature Templates that are necessary to form minimal Device Template, and attach this template + # These will be applicable for vSmart devices + + - name: 7. Create AAA Template for vSmart devices + cisco.catalystwan.feature_templates: + state: present + template_name: "AAA_for_vSmart" + template_description: "AAA Template for testing" + device_models: vsmart + debug: true + aaa: + auth_fallback: false + admin_auth_order: false + accounting: false + usergroup: + - name: basic + task: + - mode: system + permission: + - read + - mode: interface + permission: + - read + - name: netadmin + task: [] + - name: operator + task: + - mode: system + permission: + - read + - mode: interface + permission: + - read + - mode: policy + permission: + - read + - mode: routing + permission: + - read + - mode: security + permission: + - read + user: + - name: admin + password: Cisco#123@ViptelaXDD + manager_credentials: + <<: *manager_authentication + + - name: 8. Create System Template for vSmart devices + cisco.catalystwan.feature_templates: + state: present + template_name: "System_for_vSmart" + template_description: "System Template for testing" + device_specific_variables: + site_id: "side_id_variable" + device_models: vsmart + debug: true + system_vsmart: + site_id: device_specific_variable + manager_credentials: + <<: *manager_authentication + + # Now for vpn and vpn interfaces, and then attach device template with device specific variables + - name: 9. Create VPN template for vSmart devices - VPN 0 + cisco.catalystwan.feature_templates: + state: present + template_name: "VPN_0_for_vSmart" + template_description: "VPN_0 Template for testing" + device_models: vsmart + debug: true + vpn_vsmart: + vpn_id: 0 + manager_credentials: + <<: *manager_authentication + + - name: 10. Create VPN template for vSmart devices - VPN 512 + cisco.catalystwan.feature_templates: + state: present + template_name: "VPN_512_for_vSmart" + template_description: "VPN_512 Template for testing" + device_models: vsmart + debug: true + vpn_vsmart: + vpn_id: 512 + manager_credentials: + <<: *manager_authentication + + - name: 11. Create VPN Interface template for vSmart devices - VPN 0 + cisco.catalystwan.feature_templates: + state: present + template_name: "VPN_0_Interface_for_vSmart" + template_description: "VPN_0 Interface Template for testing" + device_models: vsmart + debug: true + vpn_vsmart_interface: + if_name: eth1 + shutdown: false + dhcp_ipv4_client: true + dhcp: true + dns: true + icmp: true + sshd: true + netconf: true + ntp: false + stun: false + manager_credentials: + <<: *manager_authentication + + - name: 12. Create VPN Interface template for vSmart devices - VPN 512 + cisco.catalystwan.feature_templates: + state: present + template_name: "VPN_512_Interface_for_vSmart" + template_description: "VPN_512 Interface Template for testing" + device_models: vsmart + debug: true + vpn_vsmart_interface: + if_name: eth0 + shutdown: false + dhcp_ipv4_client: true + manager_credentials: + <<: *manager_authentication + + - name: 13. Create example Device Template for vSmart + cisco.catalystwan.device_templates: + state: present + template_name: "vSmart-test-device-template" + template_description: "vSmart-test-device-template" + device_type: vsmart + general_templates: + - name: "System_for_vSmart" + subtemplates: + - "Factory_Default_Logging_Template_V01" + - name: "AAA_for_vSmart" + - name: "Factory_Default_vSmart_OMP_Template" + - name: "Factory_Default_vSmart_vManage_Security_Template" + - name: "VPN_0_for_vSmart" + subtemplates: + - "VPN_0_Interface_for_vSmart" + - name: "VPN_512_for_vSmart" + subtemplates: + - "VPN_512_Interface_for_vSmart" + manager_credentials: + <<: *manager_authentication + + - name: 14. Attach example Device Template for vSmart + cisco.catalystwan.device_templates: + state: attached + template_name: "vSmart-test-device-template" + device_type: vsmart + hostname: "acich-rg-vSmart" + device_specific_vars: + - "//system/site-id": "333" + - "//system/host-name": "acich-rg-vSmart" + - "//system/system-ip": "192.168.2.1" + - "//system/ipv6-strict-control": false + manager_credentials: + <<: *manager_authentication diff --git a/playbooks/tests/test_templates_removal.yml b/playbooks/tests/test_templates_removal.yml new file mode 100644 index 0000000..ed1af14 --- /dev/null +++ b/playbooks/tests/test_templates_removal.yml @@ -0,0 +1,60 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +--- + +# Helper playbooks to test modules and flows while developing them + +# Tested operations: + + +- name: Testing playbook to verify cisco.catalystwan.device_templates module operations + hosts: localhost + gather_facts: false + vars_files: + - configuration_file_dev_vars.yml + vars: + manager_authentication: &manager_authentication + url: "{{ (vmanage_instances | first).mgmt_public_ip }}" + username: "{{ (vmanage_instances | first).admin_username }}" + password: "{{ (vmanage_instances | first).admin_password }}" + tasks: + - name: 1. Get all Device Templates that are not attached to any device + cisco.catalystwan.device_templates_info: + filters: + devices_attached: 0 + factory_default: false + manager_credentials: + <<: *manager_authentication + register: device_templates + + - name: 2. Delete selected Device Templates from vManage + cisco.catalystwan.device_templates: + state: absent + template_name: "{{ device_template.name }}" + manager_credentials: + <<: *manager_authentication + loop: "{{ device_templates.templates_info | default([], True) }}" + loop_control: + loop_var: device_template + when: device_templates.templates_info | length > 0 + + - name: 3. Get all Non-Default Feature Templates available + cisco.catalystwan.feature_templates_info: + filters: + factory_default: false + devices_attached: 0 + manager_credentials: + <<: *manager_authentication + register: feature_templates + + - name: 4. Delete all Non-Default Feature templates + cisco.catalystwan.feature_templates: + state: absent + template_name: "{{ template.name }}" + manager_credentials: + <<: *manager_authentication + loop: "{{ feature_templates.templates_info | default([], true) }}" + loop_control: + loop_var: template + label: "template: {{ template.name }}" diff --git a/plugins/README.md b/plugins/README.md index e5e4cf3..47505f7 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -66,6 +66,22 @@ Proposed common Return Values: --- +## Feature Templates contribution + +Module [feature_templaes](../plugins/modules/feature_templates.py) provide option to add Feature Templates. +This module is highly relaying on existing models of Feature Templates in Catalystwan SDK. If there is a missing +template that you want to use, you can contribute, and first add that model in Catalystwan SDK (important node: available_models dictionary is still used to determine which templates are supported) + +When required model is already there, you can reuse [script for generating documentation and module args](../utils/ft_generator.py) (simply by running it as python script). If your model was correctly added in Catalystwan SDK, script should create 2 files: + +* first one in `plugins/doc_fragments/` directory with .yml extension -> this one contains all documentation for that template in Ansible module + +* second one in `plugins/module_utils/feature_templates` directory with .py extension -> this one contains all module args that can be reuse later in Ansible module + +With these 2 files, you can extend `feature_templates` module by using `extends_documentation_fragment` fragment in DOCUMENTATION block, and also by using `module_args` dictionary extended by unpacked dictionary coming from `plugins/module_utils/feature_templates` file. + +--- + ## Providing credentials to catalystwan Ansible modules There are 3 ways to provide information to module about vManage you want to work with. diff --git a/plugins/doc_fragments/__init__.py b/plugins/doc_fragments/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugins/doc_fragments/device_models_device_template.py b/plugins/doc_fragments/device_models_device_template.py new file mode 100644 index 0000000..cde723c --- /dev/null +++ b/plugins/doc_fragments/device_models_device_template.py @@ -0,0 +1,87 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + device_type: + description: + - Defines the SD-WAN device type for template application. + type: str + required: false + aliases: [device_model] + choices: + - "vsmart" + - "vedge-cloud" + - "vmanage" + - "vedge-ISR1100-6G" + - "vedge-ISR1100X-6G" + - "vedge-ISR1100-4G" + - "vedge-ISR1100X-4G" + - "vedge-ISR1100-4GLTE" + - "vedge-1000" + - "vedge-2000" + - "vedge-100" + - "vedge-100-B" + - "vedge-100-WM" + - "vedge-100-M" + - "vedge-5000" + - "vedge-IR-1101" + - "vedge-ESR-6300" + - "vedge-IR-1821" + - "vedge-IR-1831" + - "vedge-IR-1833" + - "vedge-IR-1835" + - "vedge-ASR-1001-X" + - "vedge-ASR-1002-X" + - "vedge-ASR-1002-HX" + - "vedge-ASR-1001-HX" + - "vedge-C8500L-8G4X" + - "vedge-C8500-12X4QC" + - "vedge-C8500-12X" + - "vedge-C8500L-8S4X" + - "vedge-ASR-1006-X" + - "vedge-C8500-20X6C" + - "vedge-CSR-1000v" + - "vedge-C8000V" + - "vedge-ISR-4331" + - "vedge-ISR-4431" + - "vedge-ISR-4461" + - "vedge-ISR-4451-X" + - "vedge-ISR-4321" + - "vedge-ISR-4351" + - "vedge-ISR-4221" + - "vedge-ISR-4221X" + - "vedge-C1111-8PW" + - "vedge-C1111-8PLTELAW" + - "vedge-C1111-8PLTEEAW" + - "vedge-C1113-8PMLTEEA" + - "vedge-C1116-4P" + - "vedge-C1116-4PLTEEA" + - "vedge-C1117-4P" + - "vedge-C1117-4PM" + - "vedge-C1117-4PLTEEA" + - "vedge-C1111-8PLTELA" + - "vedge-C1111-8PLTEEA" + - "vedge-C1121-8PLTEPW" + - "vedge-C1121-8PLTEP" + - "vedge-C1121X-8PLTEP" + - "vedge-C1111-4PLTEEA" + - "vedge-C1161X-8PLTEP" + - "vedge-C8300-2N2S-6T" + - "vedge-C8300-1N1S-6T" + - "vedge-C8300-1N1S-4T2X" + - "vedge-C8300-2N2S-4T2X" + - "vedge-C8200-1N-4T" + - "vedge-C8200L-1N-4T" + - "vedge-ISRv" + """ diff --git a/plugins/doc_fragments/device_models_feature_template.py b/plugins/doc_fragments/device_models_feature_template.py new file mode 100644 index 0000000..f9ff45d --- /dev/null +++ b/plugins/doc_fragments/device_models_feature_template.py @@ -0,0 +1,88 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + device_models: + description: + - Defines the SD-WAN device type for template application. + type: list + default: [] + elements: str + choices: + - "None" + - "vsmart" + - "vedge-cloud" + - "vmanage" + - "vedge-ISR1100-6G" + - "vedge-ISR1100X-6G" + - "vedge-ISR1100-4G" + - "vedge-ISR1100X-4G" + - "vedge-ISR1100-4GLTE" + - "vedge-1000" + - "vedge-2000" + - "vedge-100" + - "vedge-100-B" + - "vedge-100-WM" + - "vedge-100-M" + - "vedge-5000" + - "vedge-IR-1101" + - "vedge-ESR-6300" + - "vedge-IR-1821" + - "vedge-IR-1831" + - "vedge-IR-1833" + - "vedge-IR-1835" + - "vedge-ASR-1001-X" + - "vedge-ASR-1002-X" + - "vedge-ASR-1002-HX" + - "vedge-ASR-1001-HX" + - "vedge-C8500L-8G4X" + - "vedge-C8500-12X4QC" + - "vedge-C8500-12X" + - "vedge-C8500L-8S4X" + - "vedge-ASR-1006-X" + - "vedge-C8500-20X6C" + - "vedge-CSR-1000v" + - "vedge-C8000V" + - "vedge-ISR-4331" + - "vedge-ISR-4431" + - "vedge-ISR-4461" + - "vedge-ISR-4451-X" + - "vedge-ISR-4321" + - "vedge-ISR-4351" + - "vedge-ISR-4221" + - "vedge-ISR-4221X" + - "vedge-C1111-8PW" + - "vedge-C1111-8PLTELAW" + - "vedge-C1111-8PLTEEAW" + - "vedge-C1113-8PMLTEEA" + - "vedge-C1116-4P" + - "vedge-C1116-4PLTEEA" + - "vedge-C1117-4P" + - "vedge-C1117-4PM" + - "vedge-C1117-4PLTEEA" + - "vedge-C1111-8PLTELA" + - "vedge-C1111-8PLTEEA" + - "vedge-C1121-8PLTEPW" + - "vedge-C1121-8PLTEP" + - "vedge-C1121X-8PLTEP" + - "vedge-C1111-4PLTEEA" + - "vedge-C1161X-8PLTEP" + - "vedge-C8300-2N2S-6T" + - "vedge-C8300-1N1S-6T" + - "vedge-C8300-1N1S-4T2X" + - "vedge-C8300-2N2S-4T2X" + - "vedge-C8200-1N-4T" + - "vedge-C8200L-1N-4T" + - "vedge-ISRv" + """ diff --git a/plugins/doc_fragments/feature_template_aaa.py b/plugins/doc_fragments/feature_template_aaa.py new file mode 100644 index 0000000..6047db1 --- /dev/null +++ b/plugins/doc_fragments/feature_template_aaa.py @@ -0,0 +1,443 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + aaa: + description: AAA Feature Template configuration + type: dict + suboptions: + auth_order: + description: + - ServerGroups authentication order to user access + required: false + default: + - local + - radius + - tacacs + type: list + elements: str + choices: + - local + - radius + - tacacs + auth_fallback: + description: + - Authenticate admin user as per auth-order + required: false + default: false + type: bool + admin_auth_order: + description: + - Fall back if higher-priority authentication fails + required: false + default: false + type: bool + netconf_disable: + description: + - Disable Netconf logs + required: false + default: false + type: bool + audit_disable: + description: + - Disable audit logs + required: false + default: false + type: bool + radius_server_list: + description: + - Designate radius servers for authentication and accounting + required: false + default: null + type: list + elements: str + task: + description: + - Set the user group's tasks and task privileges. + required: false + default: null + type: list + elements: dict + suboptions: + name: + description: + - The name of the user + required: true + default: null + type: str + config_default_action: + description: + - Define config default action + required: true + default: null + type: str + choices: + - accept + - deny + oper_exec_default_action: + description: + - Define oper-exec default action + required: true + default: null + type: str + choices: + - accept + - deny + oper_exec_accept_action: + description: + - List of oper-exec commands to allow + required: false + default: null + type: list + elements: dict + suboptions: + command: + description: + - Define command + required: true + default: null + type: str + oper_exec_deny_action: + description: + - List of oper-exec commands to deny + required: false + default: null + type: list + elements: dict + suboptions: + command: + description: + - Define command + required: true + default: null + type: str + config_accept_action: + description: + - List of config commands to allow + required: false + default: null + type: list + elements: dict + suboptions: + command: + description: + - Define command + required: true + default: null + type: str + config_deny_action: + description: + - List of config commands to deny + required: false + default: null + type: list + elements: dict + suboptions: + command: + description: + - Define command + required: true + default: null + type: str + password: + description: + - The password for the user + required: false + default: null + type: str + secret: + description: + - The secret for the user + required: false + default: null + type: str + privilege: + description: + - The privilege level for the user + required: false + default: '15' + type: str + choices: + - '1' + - '15' + accounting: + description: + - Enable/disable user accounting + required: false + default: false + type: bool + usergroup: + description: + - Create groupings of users with the same authorization privileges. + When used, overrides existing groups(netadmin, basic, operator) + required: false + default: null + type: list + elements: dict + suboptions: + name: + description: + - Set name of user group + required: true + default: null + type: str + task: + description: + - Set the user group's tasks and task privileges. Skipping + tasks sets all as read and write + required: false + default: null + type: list + elements: dict + suboptions: + mode: + description: + - Select the task to set privileges for + required: true + default: null + type: str + choices: + - system + - interface + - policy + - routing + - security + permission: + description: + - Set read or write permission for the task + required: false + default: pap + type: list + elements: str + choices: + - read + - write + user: + description: + - List of local user configurations. When used, overrides existing + users + required: false + default: null + type: list + elements: dict + suboptions: + name: + description: + - The name of the user + required: true + default: null + type: str + password: + description: + - The password for the user + required: false + default: null + type: str + secret: + description: + - The secret for the user + required: false + default: null + type: str + description: + description: + - Add a description of the user + required: false + default: null + type: str + group: + description: + - Configure the groups that the user is part of + required: false + default: null + type: list + elements: str + pubkey_chain: + description: + - List of public keys for the user + required: false + default: null + type: list + elements: dict + suboptions: + usertag: + description: + - User Tag + required: true + default: null + type: str + key_string: + description: + - Set the RSA key string + required: true + default: null + type: str + key_type: + description: + - Only RSA is supported + required: false + default: ssh-rsa + type: str + cisco_tac_ro_user: + description: + - Cisco Tac Enable Read only + required: false + default: true + type: bool + cisco_tac_rw_user: + description: + - Cisco Tac Enable Read and Write + required: false + default: true + type: bool + tacacs_timeout: + description: + - The timeout period in seconds for the TACACS+ server + required: false + default: null + type: int + tacacs_authentication: + description: + - TACACS authentication type + required: false + default: pap + type: str + choices: + - pap + - ascii + tacacs_server: + description: + - The list of TACACS+ servers + required: false + default: null + type: list + elements: dict + suboptions: + address: + description: + - The IP address or hostname of the TACACS+ server + required: true + default: null + type: str + auth_port: + description: + - The authentication port for the TACACS+ server + required: false + default: null + type: int + vpn: + description: + - Set VPN in which TACACS+ server is located + required: false + default: null + type: str + source_interface: + description: + - Set interface to use to reach TACACS+ server + required: false + default: null + type: str + key: + description: + - Set the password to access the TACACS+ server + required: false + default: null + type: str + secret_key: + description: + - Set the AES encrypted key to access the TACACS+ server + required: false + default: null + type: str + priority: + description: + - TACACS+ server priority <0..7> + required: false + default: null + type: int + radius_timeout: + description: + - The timeout period in seconds for the RADIUS server + required: false + default: null + type: int + radius_retransmit: + description: + - The number of retransmit attempts for the RADIUS server + required: false + default: null + type: int + radius_server: + description: + - The list of RADIUS servers + required: false + default: null + type: list + elements: dict + suboptions: + address: + description: + - The IP address or hostname of the RADIUS server + required: true + default: null + type: str + auth_port: + description: + - The authentication port for the RADIUS server + required: false + default: null + type: int + tag: + description: + - Reference tag/name for the server + required: false + default: null + type: str + acct_port: + description: + - The accounting port for the RADIUS server + required: false + default: null + type: int + vpn: + description: + - Set VPN in which RADIUS server is located + required: false + default: null + type: str + source_interface: + description: + - Set interface to use to reach RADIUS server + required: false + default: null + type: str + key: + description: + - Set the password to access the RADIUS server + required: false + default: null + type: str + secret_key: + description: + - Set the AES encrypted key to access the RADIUS server + required: false + default: null + type: str + priority: + description: + - RADIUS server priority <0..7> + required: false + default: null + type: int + """ diff --git a/plugins/doc_fragments/feature_template_cisco_aaa.py b/plugins/doc_fragments/feature_template_cisco_aaa.py new file mode 100644 index 0000000..0d1ed35 --- /dev/null +++ b/plugins/doc_fragments/feature_template_cisco_aaa.py @@ -0,0 +1,433 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + cisco_aaa: + description: Cisco AAA Feature Template configuration + type: dict + suboptions: + authentication_group: + description: + - 'Whether to enable the authentication group, GUI equivalent: Authentication + Param' + required: false + default: false + type: bool + accounting_group: + description: + - 'Whether to enable the accounting group, GUI equivalent: Accounting + Param' + required: false + default: false + type: bool + server_auth_order: + description: + - ServerGroups authentication order to user access + required: false + default: local + type: str + user: + description: + - List of local user configurations + required: false + default: null + type: list + elements: dict + suboptions: + name: + description: + - The name of the user + required: true + default: null + type: str + password: + description: + - The password for the user + required: false + default: null + type: str + secret: + description: + - The secret for the user + required: false + default: null + type: str + privilege: + description: + - The privilege level for the user + required: false + default: '15' + type: str + choices: + - '1' + - '15' + pubkey_chain: + description: + - List of public keys for the user + required: false + default: null + type: list + elements: dict + suboptions: + key_string: + description: + - Set the RSA key string + required: true + default: null + type: str + key_type: + description: + - Only RSA is supported + required: false + default: ssh-rsa + type: str + accounting_rules: + description: + - Configure the accounting rules + required: false + default: null + type: list + elements: dict + suboptions: + rule_id: + description: + - Accounting Rule ID + required: true + default: null + type: str + method: + description: + - Configure Accounting Method + required: true + default: null + type: str + choices: + - commands + - exec + - network + - system + level: + description: + - Privilege level when method is commands + required: false + default: null + type: str + choices: + - '1' + - '15' + start_stop: + description: + - Enable Start-Stop + required: false + default: true + type: bool + group: + description: + - List of groups. + required: true + default: null + type: str + authorization_console: + description: + - For enabling console authorization + required: false + default: null + type: bool + authorization_config_commands: + description: + - For configuration mode commands + required: false + default: null + type: bool + authorization_rules: + description: + - Configure the accounting rules + required: false + default: null + type: list + elements: dict + suboptions: + rule_id: + description: + - Authorization Rule ID + required: true + default: null + type: str + method: + description: + - Configure Authorization Method + required: true + default: null + type: str + choices: + - commands + level: + description: + - Privilege level when method is commands + required: false + default: null + type: str + choices: + - '1' + - '15' + group: + description: + - List of groups. + required: true + default: null + type: str + authenticated: + description: + - Succeed if user has authenticated + required: false + default: false + type: bool + radius: + description: + - List of Radius group configurations + required: false + default: null + type: list + elements: dict + suboptions: + group_name: + description: + - The name of the RADIUS group + required: true + default: null + type: str + vpn: + description: + - The VPN ID for the RADIUS group + required: true + default: null + type: int + source_interface: + description: + - The source interface for the RADIUS group + required: true + default: null + type: str + server: + description: + - The list of RADIUS servers for the group + required: false + default: [] + type: list + elements: dict + suboptions: + address: + description: + - The IP address or hostname of the RADIUS server + required: true + default: null + type: str + auth_port: + description: + - The authentication port for the RADIUS server + required: false + default: null + type: int + acct_port: + description: + - The accounting port for the RADIUS server + required: false + default: null + type: int + timeout: + description: + - The timeout period in seconds for the RADIUS server + required: false + default: null + type: int + retransmit: + description: + - The number of retransmit attempts for the RADIUS + server + required: false + default: null + type: int + key: + description: + - The key for the RADIUS server + required: true + default: null + type: str + secret_key: + description: + - The secret key for the RADIUS server + required: false + default: null + type: str + key_enum: + description: + - The key enumeration for the RADIUS server + required: false + default: null + type: str + key_type: + description: + - The key type for the RADIUS server + required: false + default: null + type: str + radius_client: + description: + - Specify a RADIUS client + required: false + default: null + type: list + elements: dict + suboptions: + ip: + description: + - The Client IP + required: true + default: null + type: str + vpn: + description: + - The VPN Configuration + required: true + default: null + type: list + elements: dict + suboptions: + name: + description: + - VPN ID + required: true + default: null + type: str + server_key: + description: + - Specify a RADIUS client server-key + required: false + default: null + type: str + domain_stripping: + description: + - The domain stripping configuration + required: false + default: null + type: str + choices: + - 'yes' + - 'no' + - right-to-left + authentication_type: + description: + - Authentication Type + required: false + default: any + type: str + choices: + - any + - all + - session-key + port: + description: + - Specify Radius Dynamic Author Port + required: false + default: null + type: int + server_key_password: + description: + - Specify a radius dynamic author server-key + required: false + default: null + type: str + cts_authorization_list: + description: + - Specify a radius dynamic author server-key + required: false + default: null + type: str + radius_trustsec_group: + description: + - RADIUS trustsec group + required: false + default: null + type: str + tacacs: + description: + - List of TACACS group configurations + required: false + default: null + type: list + elements: dict + suboptions: + group_name: + description: + - The name of the TACACS+ group + required: true + default: null + type: str + vpn: + description: + - The VPN ID for the TACACS+ group + required: false + default: null + type: int + source_interface: + description: + - The source interface for the TACACS+ group + required: false + default: null + type: str + server: + description: + - The list of TACACS+ servers for the group + required: false + default: [] + type: list + elements: dict + suboptions: + address: + description: + - The IP address or hostname of the TACACS+ server + required: true + default: null + type: str + key: + description: + - The key for the TACACS+ server + required: true + default: null + type: str + port: + description: + - The port for the TACACS+ server + required: false + default: null + type: int + timeout: + description: + - The timeout period in seconds for the TACACS+ server + required: false + default: null + type: int + secret_key: + description: + - The secret key for the TACACS+ server + required: false + default: null + type: str + key_enum: + description: + - The key enumeration for the TACACS+ server + required: false + default: null + type: str + """ diff --git a/plugins/doc_fragments/feature_template_cisco_banner.py b/plugins/doc_fragments/feature_template_cisco_banner.py new file mode 100644 index 0000000..458aea4 --- /dev/null +++ b/plugins/doc_fragments/feature_template_cisco_banner.py @@ -0,0 +1,33 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + cisco_banner: + description: Cisco Banner configuration for login and message of the day (MOTD) + type: dict + suboptions: + login_banner: + description: + - The login banner text displayed before authentication + required: false + default: null + type: str + motd_banner: + description: + - The message of the day (MOTD) banner text displayed after successful + authentication + required: false + default: null + type: str + """ diff --git a/plugins/doc_fragments/feature_template_cisco_bfd.py b/plugins/doc_fragments/feature_template_cisco_bfd.py new file mode 100644 index 0000000..4c7867c --- /dev/null +++ b/plugins/doc_fragments/feature_template_cisco_bfd.py @@ -0,0 +1,100 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + cisco_bfd: + description: Cisco Bidirectional Forwarding Detection (BFD) configuration + type: dict + suboptions: + multiplier: + description: + - The default BFD multiplier for all colors + required: false + default: null + type: int + poll_interval: + description: + - The BFD poll interval in milliseconds + required: false + default: null + type: int + default_dscp: + description: + - The default DSCP value for BFD packets + required: false + default: null + type: int + color: + description: + - List of color-specific BFD configurations + required: false + default: null + type: list + elements: dict + suboptions: + color: + description: + - The color of the BFD session, representing various transport + types + required: true + default: null + type: str + choices: + - default + - mpls + - metro-ethernet + - biz-internet + - public-internet + - lte + - 3g + - red + - green + - blue + - gold + - silver + - bronze + - custom1 + - custom2 + - custom3 + - private1 + - private2 + - private3 + - private4 + - private5 + - private6 + hello_interval: + description: + - The BFD hello interval in milliseconds + required: false + default: null + type: int + multiplier: + description: + - The BFD multiplier for the color + required: false + default: null + type: int + pmtu_discovery: + description: + - Whether to enable Path MTU Discovery + required: false + default: true + type: bool + dscp: + description: + - The DSCP value used for BFD packets + required: false + default: null + type: int + """ diff --git a/plugins/doc_fragments/feature_template_cisco_logging.py b/plugins/doc_fragments/feature_template_cisco_logging.py new file mode 100644 index 0000000..47434cb --- /dev/null +++ b/plugins/doc_fragments/feature_template_cisco_logging.py @@ -0,0 +1,195 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + cisco_logging: + description: Cisco Logging Feature Template configuration + type: dict + suboptions: + enable: + description: + - Whether logging to disk is enabled + required: false + default: null + type: bool + size: + description: + - The maximum file size for the log file + required: false + default: null + type: int + rotate: + description: + - The number of log files to maintain before rotating + required: false + default: null + type: int + tls_profile: + description: + - List of TLS profiles configurations + required: false + default: null + type: list + elements: dict + suboptions: + profile: + description: + - The name of the TLS profile + required: true + default: null + type: str + version: + description: + - The TLS version + required: false + default: TLSv1.1 + type: str + choices: + - TLSv1.1 + - TLSv1.2 + auth_type: + description: + - The authentication type for the TLS connection + required: true + default: null + type: str + choices: + - Server + - Mutual + ciphersuite_list: + description: + - The list of ciphersuites for the TLS connection + required: false + default: null + type: list + elements: str + server: + description: + - List of server configurations for logging + required: false + default: null + type: list + elements: dict + suboptions: + name: + description: + - The hostname/IPv4 address of the server + required: true + default: null + type: str + vpn: + description: + - The VPN ID for the server + required: true + default: null + type: int + source_interface: + description: + - The source interface for the server + required: false + default: null + type: str + priority: + description: + - The priority level for logging messages + required: false + default: information + type: str + choices: + - information + - debugging + - notice + - warn + - error + - critical + - alert + - emergency + enable_tls: + description: + - Whether to enable TLS encryption + required: false + default: false + type: bool + custom_profile: + description: + - Whether to use a custom TLS profile + required: false + default: false + type: bool + profile: + description: + - The custom TLS profile to use + required: false + default: null + type: str + ipv6_server: + description: + - List of IPv6 server configurations for logging + required: false + default: null + type: list + elements: dict + suboptions: + name: + description: + - The name of the IPv6 server + required: true + default: null + type: str + vpn: + description: + - The VPN ID for the IPv6 server + required: true + default: null + type: int + source_interface: + description: + - The source interface for the IPv6 server + required: false + default: null + type: str + priority: + description: + - The priority level for logging messages to the IPv6 server + required: false + default: information + type: str + choices: + - information + - debugging + - notice + - warn + - error + - critical + - alert + - emergency + enable_tls: + description: + - Whether to enable TLS encryption for the IPv6 server + required: false + default: false + type: bool + custom_profile: + description: + - Whether to use a custom TLS profile for the IPv6 server + required: false + default: false + type: bool + profile: + description: + - The custom TLS profile to use for the IPv6 server + required: false + default: null + type: str + """ diff --git a/plugins/doc_fragments/feature_template_cisco_ntp.py b/plugins/doc_fragments/feature_template_cisco_ntp.py new file mode 100644 index 0000000..dc662a9 --- /dev/null +++ b/plugins/doc_fragments/feature_template_cisco_ntp.py @@ -0,0 +1,109 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + cisco_ntp: + description: Cisco NTP Feature Template configuration + type: dict + suboptions: + server: + description: + - List of NTP servers + required: false + default: [] + type: list + elements: dict + suboptions: + name: + description: + - The hostname or IP address of the NTP server + required: true + default: null + type: str + key: + description: + - The identifier for the authentication key + required: false + default: null + type: int + vpn: + description: + - The VPN ID associated with the NTP server + required: false + default: null + type: int + version: + description: + - The NTP version used + required: false + default: null + type: int + source_interface: + description: + - The source interface for NTP messages + required: false + default: null + type: str + prefer: + description: + - Whether this server is preferred over others + required: false + default: null + type: bool + authentication: + description: + - List of authentication keys + required: false + default: null + type: list + elements: dict + suboptions: + number: + description: + - The authentication key number + required: true + default: null + type: int + md5: + description: + - The MD5 hash used for authentication + required: true + default: null + type: str + trusted: + description: + - List of trusted key numbers + required: false + default: null + type: list + elements: int + enable: + description: + - Whether the device is an NTP master + required: false + default: null + type: bool + stratum: + description: + - The stratum level if the device is an NTP master + required: false + default: null + type: int + source: + description: + - The source interface for NTP messages if the device is an NTP master + required: false + default: null + type: str + """ diff --git a/plugins/doc_fragments/feature_template_cisco_omp.py b/plugins/doc_fragments/feature_template_cisco_omp.py new file mode 100644 index 0000000..3024d07 --- /dev/null +++ b/plugins/doc_fragments/feature_template_cisco_omp.py @@ -0,0 +1,180 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + cisco_omp: + description: Configuration settings for the Cisco Overlay Management Protocol + (OMP) feature template. + type: dict + suboptions: + graceful_restart: + description: + - Enable or disable graceful restart for OMP. + required: false + default: true + type: bool + overlay_as: + description: + - The autonomous system number used for the overlay. + required: false + default: null + type: int + send_path_limit: + description: + - The maximum number of paths that can be sent for each prefix. + required: false + default: null + type: int + ecmp_limit: + description: + - The maximum number of equal-cost multi-path routes. + required: false + default: null + type: int + shutdown: + description: + - Enable or disable the shutdown of OMP. + required: false + default: null + type: bool + omp_admin_distance_ipv4: + description: + - The administrative distance for IPv4 routes learned via OMP. + required: false + default: null + type: int + omp_admin_distance_ipv6: + description: + - The administrative distance for IPv6 routes learned via OMP. + required: false + default: null + type: int + advertisement_interval: + description: + - The interval between sending unsolicited OMP route advertisements. + required: false + default: null + type: int + graceful_restart_timer: + description: + - The timer for graceful restart, specifying the period during which + peerings are preserved. + required: false + default: null + type: int + eor_timer: + description: + - End-of-RIB (EOR) timer which indicates stability of the route table. + required: false + default: null + type: int + holdtime: + description: + - The amount of time that the routes are preserved while the peer + is unreachable. + required: false + default: null + type: int + advertise: + description: + - A list of IPv4 advertise rules. + required: false + default: null + type: list + elements: dict + suboptions: + protocol: + description: + - The IPv4 routing protocol whose routes are to be advertised. + required: true + default: null + type: str + choices: + - bgp + - ospf + - ospfv3 + - connected + - static + - eigrp + - lisp + - isis + route: + description: + - The type of IPv4 routes to be advertised. For example, 'external' + for external routes. + required: false + default: null + type: str + choices: + - external + ipv6_advertise: + description: + - A list of IPv6 advertise rules. + required: false + default: null + type: list + elements: dict + suboptions: + protocol: + description: + - The IPv6 routing protocol whose routes are to be advertised. + required: true + default: null + type: str + choices: + - bgp + - ospf + - connected + - static + - eigrp + - lisp + - isis + ignore_region_path_length: + description: + - Whether to ignore the region part of the path length for OMP routes. + required: false + default: false + type: bool + transport_gateway: + description: + - Specifies the preferred transport gateway selection strategy. + required: false + default: null + type: str + choices: + - prefer + - ecmp-with-direct-path + site_types: + description: + - A list of site types that are allowed to participate in the overlay + network. + required: false + default: null + type: list + elements: str + choices: + - type-1 + - type-2 + - type-3 + - cloud + - branch + - br + - spoke + auto_translate: + description: + - Enable or disable automatic translation of network settings. + required: false + default: false + type: bool + """ diff --git a/plugins/doc_fragments/feature_template_cisco_ospf.py b/plugins/doc_fragments/feature_template_cisco_ospf.py new file mode 100644 index 0000000..e56b9b8 --- /dev/null +++ b/plugins/doc_fragments/feature_template_cisco_ospf.py @@ -0,0 +1,325 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + cisco_ospf: + description: Cisco OSPF (Open Shortest Path First) configuration + type: dict + suboptions: + router_id: + description: + - The router ID of the OSPF process. + required: false + default: null + type: str + reference_bandwidth: + description: + - The reference bandwidth used by OSPF for cost calculation. + required: false + default: null + type: int + rfc1583: + description: + - Compatibility switch for RFC 1583. + required: false + default: true + type: bool + originate: + description: + - Controls the origination of default information into the OSPF domain. + required: false + default: null + type: bool + always: + description: + - Ensures that the default route is always advertised, regardless + of the existence of a default route in the routing table. + required: false + default: null + type: bool + metric: + description: + - The metric value to be set for the default route advertised by OSPF. + required: false + default: null + type: int + metric_type: + description: + - The metric type (Type 1 or Type 2) for OSPF external routes. + required: false + default: null + type: str + choices: + - type1 + - type2 + external: + description: + - The OSPF external route metric. + required: false + default: null + type: int + inter_area: + description: + - The OSPF inter-area route metric. + required: false + default: null + type: int + intra_area: + description: + - The OSPF intra-area route metric. + required: false + default: null + type: int + delay: + description: + - The OSPF Shortest Path First (SPF) delay time. + required: false + default: null + type: int + initial_hold: + description: + - The initial hold time between consecutive SPF calculations. + required: false + default: null + type: int + max_hold: + description: + - The maximum hold time between consecutive SPF calculations. + required: false + default: null + type: int + redistribute: + description: + - A list of OSPF redistribution configurations. + required: false + default: null + type: list + elements: dict + suboptions: + protocol: + description: + - The routing protocol from which routes are to be redistributed + into OSPF. + required: true + default: null + type: str + choices: + - static + - connected + - bgp + - omp + - nat + - eigrp + route_policy: + description: + - Name of the route policy to control the redistribution. + required: false + default: null + type: str + dia: + description: + - Default information originate, which controls the advertisement + of default route. + required: false + default: true + type: bool + router_lsa: + description: + - Configuration options for the Router LSA in OSPF. + required: false + default: null + type: list + elements: dict + suboptions: + ad_type: + description: + - Type of advertisement for the router LSA. + required: true + default: null + type: str + choices: + - administrative + - on-startup + time: + description: + - Time in seconds for advertisement. + required: true + default: null + type: int + route_policy: + description: + - A list of OSPF route policies. + required: false + default: null + type: list + elements: dict + suboptions: + direction: + description: + - Direction of the route policy (e.g., 'in' for incoming). + required: true + default: null + type: str + choices: + - in + pol_name: + description: + - Name of the route policy. + required: true + default: null + type: str + area: + description: + - A list of OSPF areas and their configurations. + required: false + default: null + type: list + elements: dict + suboptions: + a_num: + description: + - The OSPF area number. + required: true + default: null + type: int + stub: + description: + - Configuration for the OSPF area to be a stub area. If set, + no-summary can be applied. + required: false + default: null + type: bool + nssa: + description: + - Configuration for the OSPF area to be a Not-So-Stubby Area + (NSSA). If set, no-summary can be applied. + required: false + default: null + type: bool + interface: + description: + - A list of OSPF interface configurations associated with + this area. + required: false + default: null + type: list + elements: dict + suboptions: + name: + description: + - The name of the OSPF interface. + required: true + default: null + type: str + hello_interval: + description: + - The interval between the OSPF Hello packets that + the router sends on the interface. + required: false + default: null + type: int + dead_interval: + description: + - The time interval an OSPF router waits for a Hello + packet before declaring the sending router down. + required: false + default: null + type: int + retransmit_interval: + description: + - The interval between LSA retransmissions for adjacencies + belonging to the interface. + required: false + default: null + type: int + cost: + description: + - The OSPF cost (metric) for this interface. + required: false + default: null + type: int + priority: + description: + - The OSPF priority of the interface. + required: false + default: null + type: int + network: + description: + - The OSPF network type for the interface. + required: false + default: broadcast + type: str + choices: + - broadcast + - point-to-point + - non-broadcast + - point-to-multipoint + passive_interface: + description: + - Whether the interface is a passive OSPF interface. + required: false + default: false + type: bool + type: + description: + - The OSPF authentication type for the interface. + required: false + default: null + type: str + choices: + - simple + - message-digest + - 'null' + message_digest_key: + description: + - The message-digest key ID for OSPF authentication. + required: false + default: null + type: int + md5: + description: + - The MD5 string for OSPF message-digest authentication. + required: false + default: null + type: str + range: + description: + - A list of OSPF range entries to be associated with this + area. + required: false + default: null + type: list + elements: dict + suboptions: + address: + description: + - The IPv4 network address to be advertised as an + OSPF range. + required: true + default: null + type: str + cost: + description: + - The OSPF cost (metric) for this range. + required: false + default: null + type: int + no_advertise: + description: + - Whether to suppress advertising this range. + required: false + default: false + type: bool + """ diff --git a/plugins/doc_fragments/feature_template_cisco_secure_internet_gateway.py b/plugins/doc_fragments/feature_template_cisco_secure_internet_gateway.py new file mode 100644 index 0000000..f93c7cc --- /dev/null +++ b/plugins/doc_fragments/feature_template_cisco_secure_internet_gateway.py @@ -0,0 +1,509 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + cisco_secure_internet_gateway: + description: Cisco Secure Internet Gateway feature template configuration + type: dict + suboptions: + vpn_id: + description: + - VPN ID associated with the Cisco Secure Internet Gateway service. + required: false + default: null + type: int + child_org_id: + description: + - Child Organization Id + required: false + default: '' + type: str + interface: + description: + - List of interface configurations associated with the service. + required: true + default: null + type: list + elements: dict + suboptions: + if_name: + description: + - Name of the interface. + required: true + default: null + type: str + auto: + description: + - Flag to indicate if the interface should be automatically + configured. + required: true + default: null + type: bool + shutdown: + description: + - Flag to indicate if the interface is administratively down + (shutdown). + required: true + default: null + type: bool + description: + description: + - Description for the interface. + required: false + default: null + type: str + unnumbered: + description: + - Flag to indicate if the interface should be unnumbered. + required: false + default: null + type: bool + address: + description: + - IPv4 address and subnet mask for the interface. + required: false + default: null + type: str + tunnel_source: + description: + - IPv4 address used as the source of the tunnel. + required: false + default: null + type: str + tunnel_source_interface: + description: + - Interface name used as the source of the tunnel. + required: false + default: null + type: str + tunnel_route_via: + description: + - The route via which tunnel traffic should be sent. + required: false + default: null + type: str + tunnel_destination: + description: + - The destination address for the tunnel. + required: true + default: null + type: str + application: + description: + - Application type for the Secure Internet Gateway. + required: false + default: sig + type: str + choices: + - sig + tunnel_set: + description: + - Tunnel set used for the Secure Internet Gateway. + required: false + default: secure-internet-gateway-umbrella + type: str + choices: + - secure-internet-gateway-umbrella + - secure-internet-gateway-zscaler + tunnel_dc_preference: + description: + - Data center preference for the tunnel. + required: false + default: primary-dc + type: str + choices: + - primary-dc + - secondary-dc + tcp_mss_adjust: + description: + - TCP Maximum Segment Size (MSS) adjust value. + required: false + default: null + type: int + mtu: + description: + - MTU (Maximum Transmission Unit) size for the interface. + required: false + default: null + type: int + dpd_interval: + description: + - Dead Peer Detection (DPD) interval in seconds. + required: false + default: null + type: int + dpd_retries: + description: + - Number of retries for Dead Peer Detection (DPD). + required: false + default: null + type: int + ike_version: + description: + - Internet Key Exchange (IKE) protocol version. + required: false + default: null + type: int + pre_shared_secret: + description: + - Pre-shared secret key for IKE authentication. + required: false + default: null + type: str + ike_rekey_interval: + description: + - Interval for rekeying the IKE security association. + required: false + default: null + type: int + ike_ciphersuite: + description: + - Ciphersuite for IKE security association establishment. + required: false + default: aes256-cbc-sha1 + type: str + choices: + - aes256-cbc-sha1 + - aes256-cbc-sha2 + - aes128-cbc-sha1 + - aes128-cbc-sha2 + ike_group: + description: + - Diffie-Hellman group used for IKE key exchange. + required: false + default: '14' + type: str + choices: + - '2' + - '14' + - '15' + - '16' + pre_shared_key_dynamic: + description: + - Flag indicating if the pre-shared key is dynamic. + required: false + default: null + type: bool + ike_local_id: + description: + - Local identifier for IKE authentication. + required: false + default: null + type: str + ike_remote_id: + description: + - Remote identifier for IKE authentication. + required: false + default: null + type: str + ipsec_rekey_interval: + description: + - Interval for rekeying the IPsec security association. + required: false + default: null + type: int + ipsec_replay_window: + description: + - Replay window size for IPsec security association. + required: false + default: null + type: int + ipsec_ciphersuite: + description: + - Ciphersuite for IPsec security association establishment. + required: false + default: aes256-gcm + type: str + choices: + - aes256-cbc-sha1 + - aes256-cbc-sha384 + - aes256-cbc-sha256 + - aes256-cbc-sha512 + - aes256-gcm + - null-sha1 + - null-sha384 + - null-sha256 + - null-sha512 + perfect_forward_secrecy: + description: + - Perfect Forward Secrecy (PFS) setting for IPsec key exchange. + required: false + default: none + type: str + choices: + - group-2 + - group-14 + - group-15 + - group-16 + - none + tracker: + description: + - Flag indicating if interface tracking is enabled. + required: false + default: null + type: bool + track_enable: + description: + - Flag indicating if tracking is enabled for the interface. + required: false + default: null + type: bool + tunnel_public_ip: + description: + - Public IP required to setup GRE tunnel to Zscaler + required: false + default: null + type: str + service: + description: + - List of service configurations for the Cisco Secure Internet Gateway. + required: true + default: null + type: list + elements: dict + suboptions: + svc_type: + description: + - Type of service configured. + required: false + default: sig + type: str + choices: + - sig + interface_pair: + description: + - List of high-availability interface pairs. + required: true + default: null + type: list + elements: dict + suboptions: + active_interface: + description: + - Name of the active interface. + required: true + default: null + type: str + active_interface_weight: + description: + - Weighting factor for the active interface, used + in failover decisions. + required: false + default: null + type: int + backup_interface: + description: + - Name of the backup interface. Can be 'None' if no + backup interface is defined. + required: false + default: null + type: str + backup_interface_weight: + description: + - Weighting factor for the backup interface, used + in failover decisions. + required: false + default: null + type: int + auth_required: + description: + - Flag indicating if authentication is required for the service. + required: false + default: null + type: bool + xff_forward_enabled: + description: + - Flag indicating if X-Forwarded-For HTTP header is enabled. + required: false + default: null + type: bool + ofw_enabled: + description: + - Flag indicating if on-premise firewall is enabled. + required: false + default: null + type: bool + ips_control: + description: + - Flag indicating if Intrusion Prevention System (IPS) control + is enabled. + required: false + default: null + type: bool + caution_enabled: + description: + - Flag indicating if caution warnings are enabled. + required: false + default: null + type: bool + primary_data_center: + description: + - Primary data center for the service. 'Auto' for automatic + selection. + required: false + default: Auto + type: str + secondary_data_center: + description: + - Secondary data center for the service. 'Auto' for automatic + selection. + required: false + default: Auto + type: str + ip: + description: + - Flag indicating if IP filtering or processing is enabled + for the service. + required: false + default: null + type: bool + idle_time: + description: + - Idle time before a session is considered inactive. + required: false + default: null + type: int + display_time_unit: + description: + - Unit of time used for displaying time-related settings. + required: false + default: MINUTE + type: str + choices: + - MINUTE + - HOUR + - DAY + ip_enforced_for_known_browsers: + description: + - Flag indicating if IP is enforced for known browsers. + required: false + default: null + type: bool + refresh_time: + description: + - Time after which the service information is refreshed. + required: false + default: null + type: int + refresh_time_unit: + description: + - Unit of time used for the refresh time setting. + required: false + default: MINUTE + type: str + choices: + - MINUTE + - HOUR + - DAY + enabled: + description: + - Flag indicating if the service is enabled. + required: false + default: null + type: bool + block_internet_until_accepted: + description: + - Flag indicating if Internet access is blocked until the + service is accepted. + required: false + default: null + type: bool + force_ssl_inspection: + description: + - Flag indicating if SSL inspection is forced. + required: false + default: null + type: bool + timeout: + description: + - Timeout value for the service, after which the session is + considered inactive. + required: false + default: null + type: int + location_name: + description: + - Secondary data center for the service. 'Auto' for automatic + selection. + required: false + default: Auto + type: str + data_center_primary: + description: + - Zscaler location name (optional) + required: false + default: Auto + type: str + data_center_secondary: + description: + - Secondary data center for the service. 'Auto' for automatic + selection or a specific identifier for a manual selection. + required: false + default: Auto + type: str + tracker_src_ip: + description: + - Source IP address used by the tracker for sending health check packets. + required: false + default: null + type: str + tracker: + description: + - List of trackers for monitoring the health of the Cisco Secure Internet + Gateway service. + required: false + default: null + type: list + elements: dict + suboptions: + name: + description: + - Name of the tracker. + required: true + default: null + type: str + endpoint_api_url: + description: + - URL of the endpoint API used by the tracker for health checks. + required: true + default: null + type: str + threshold: + description: + - Threshold value for the tracker to trigger an alert or action. + required: false + default: null + type: int + interval: + description: + - Interval at which the tracker performs health checks. + required: false + default: null + type: int + multiplier: + description: + - Multiplier value used by the tracker to escalate repeated + failures. + required: false + default: null + type: int + tracker_type: + description: + - Type of tracker used for monitoring. + required: true + default: null + type: str + choices: + - SIG + """ diff --git a/plugins/doc_fragments/feature_template_cisco_snmp.py b/plugins/doc_fragments/feature_template_cisco_snmp.py new file mode 100644 index 0000000..c497c0e --- /dev/null +++ b/plugins/doc_fragments/feature_template_cisco_snmp.py @@ -0,0 +1,226 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + cisco_snmp: + description: Cisco SNMP Feature Template configuration + type: dict + suboptions: + shutdown: + description: + - Indicates whether SNMP is administratively shut down + required: false + default: true + type: bool + contact: + description: + - The contact information for the SNMP administrator + required: false + default: null + type: str + location: + description: + - The physical location information for the SNMP agent + required: false + default: null + type: str + view: + description: + - List of SNMP views for controlling access to OIDs + required: false + default: null + type: list + elements: dict + suboptions: + name: + description: + - The name of the SNMP view + required: true + default: null + type: str + oid: + description: + - List of OIDs to include or exclude in the view + required: false + default: null + type: list + elements: dict + suboptions: + id: + description: + - The OID (Object Identifier) to include or exclude + in the view + required: true + default: null + type: str + exclude: + description: + - Indicates whether the OID should be excluded from + the view + required: false + default: null + type: bool + community: + description: + - List of SNMP communities for different access rights + required: false + default: null + type: list + elements: dict + suboptions: + name: + description: + - The name of the SNMP community + required: true + default: null + type: str + view: + description: + - The SNMP view associated with the community + required: true + default: null + type: str + authorization: + description: + - The authorization level of the community + required: true + default: null + type: str + choices: + - read-only + group: + description: + - List of SNMP groups defining security models and access rights + required: false + default: null + type: list + elements: dict + suboptions: + name: + description: + - The name of the SNMP group + required: true + default: null + type: str + security_level: + description: + - The security level associated with the group + required: true + default: null + type: str + choices: + - no-auth-no-priv + - auth-no-priv + - auth-priv + view: + description: + - The SNMP view associated with the group + required: true + default: null + type: str + user: + description: + - List of SNMP users with authentication and privacy configurations + required: false + default: null + type: list + elements: dict + suboptions: + name: + description: + - The name of the SNMP user + required: true + default: null + type: str + auth: + description: + - The authentication protocol used + required: false + default: null + type: str + choices: + - md5 + - sha + auth_password: + description: + - The password for authentication + required: false + default: null + type: str + priv: + description: + - The privacy (encryption) protocol used + required: false + default: null + type: str + choices: + - aes-cfb-128 + - aes-256-cfb-128 + priv_password: + description: + - The password for privacy + required: false + default: null + type: str + group: + description: + - The group to which the user belongs + required: true + default: null + type: str + target: + description: + - List of SNMP targets for sending traps + required: false + default: null + type: list + elements: dict + suboptions: + vpn_id: + description: + - The VPN ID where the SNMP target resides + required: true + default: null + type: int + ip: + description: + - The IP address of the SNMP target + required: true + default: null + type: str + port: + description: + - The port number for the SNMP target + required: true + default: null + type: int + community_name: + description: + - The community name for the SNMP target + required: false + default: null + type: str + user: + description: + - The user name for the SNMP target + required: false + default: null + type: str + source_interface: + description: + - The source interface for sending SNMP traps + required: false + default: null + type: str + """ diff --git a/plugins/doc_fragments/feature_template_cisco_system.py b/plugins/doc_fragments/feature_template_cisco_system.py new file mode 100644 index 0000000..4edee17 --- /dev/null +++ b/plugins/doc_fragments/feature_template_cisco_system.py @@ -0,0 +1,939 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + cisco_system: + description: Cisco System configuration settings for SD-WAN devices. + type: dict + suboptions: + timezone: + description: + - The timezone setting for the system. + required: false + default: null + type: str + choices: + - Europe/Andorra + - Asia/Dubai + - Asia/Kabul + - America/Antigua + - America/Anguilla + - Europe/Tirane + - Asia/Yerevan + - Africa/Luanda + - Antarctica/McMurdo + - Antarctica/Rothera + - Antarctica/Palmer + - Antarctica/Mawson + - Antarctica/Davis + - Antarctica/Casey + - Antarctica/Vostok + - Antarctica/DumontDUrville + - Antarctica/Syowa + - America/Argentina/Buenos_Aires + - America/Argentina/Cordoba + - America/Argentina/Salta + - America/Argentina/Jujuy + - America/Argentina/Tucuman + - America/Argentina/Catamarca + - America/Argentina/La_Rioja + - America/Argentina/San_Juan + - America/Argentina/Mendoza + - America/Argentina/San_Luis + - America/Argentina/Rio_Gallegos + - America/Argentina/Ushuaia + - Pacific/Pago_Pago + - Europe/Vienna + - Australia/Lord_Howe + - Antarctica/Macquarie + - Australia/Hobart + - Australia/Currie + - Australia/Melbourne + - Australia/Sydney + - Australia/Broken_Hill + - Australia/Brisbane + - Australia/Lindeman + - Australia/Adelaide + - Australia/Darwin + - Australia/Perth + - Australia/Eucla + - America/Aruba + - Europe/Mariehamn + - Asia/Baku + - Europe/Sarajevo + - America/Barbados + - Asia/Dhaka + - Europe/Brussels + - Africa/Ouagadougou + - Europe/Sofia + - Asia/Bahrain + - Africa/Bujumbura + - Africa/Porto-Novo + - America/St_Barthelemy + - Atlantic/Bermuda + - Asia/Brunei + - America/La_Paz + - America/Kralendijk + - America/Noronha + - America/Belem + - America/Fortaleza + - America/Recife + - America/Araguaina + - America/Maceio + - America/Bahia + - America/Sao_Paulo + - America/Campo_Grande + - America/Cuiaba + - America/Santarem + - America/Porto_Velho + - America/Boa_Vista + - America/Manaus + - America/Eirunepe + - America/Rio_Branco + - America/Nassau + - Asia/Thimphu + - Africa/Gaborone + - Europe/Minsk + - America/Belize + - America/St_Johns + - America/Halifax + - America/Glace_Bay + - America/Moncton + - America/Goose_Bay + - America/Blanc-Sablon + - America/Toronto + - America/Nipigon + - America/Thunder_Bay + - America/Iqaluit + - America/Pangnirtung + - America/Resolute + - America/Atikokan + - America/Rankin_Inlet + - America/Winnipeg + - America/Rainy_River + - America/Regina + - America/Swift_Current + - America/Edmonton + - America/Cambridge_Bay + - America/Yellowknife + - America/Inuvik + - America/Creston + - America/Dawson_Creek + - America/Vancouver + - America/Whitehorse + - America/Dawson + - Indian/Cocos + - Africa/Kinshasa + - Africa/Lubumbashi + - Africa/Bangui + - Africa/Brazzaville + - Europe/Zurich + - Africa/Abidjan + - Pacific/Rarotonga + - America/Santiago + - Pacific/Easter + - Africa/Douala + - Asia/Shanghai + - Asia/Harbin + - Asia/Chongqing + - Asia/Urumqi + - Asia/Kashgar + - America/Bogota + - America/Costa_Rica + - America/Havana + - Atlantic/Cape_Verde + - America/Curacao + - Indian/Christmas + - Asia/Nicosia + - Europe/Prague + - Europe/Berlin + - Europe/Busingen + - Africa/Djibouti + - Europe/Copenhagen + - America/Dominica + - America/Santo_Domingo + - Africa/Algiers + - America/Guayaquil + - Pacific/Galapagos + - Europe/Tallinn + - Africa/Cairo + - Africa/El_Aaiun + - Africa/Asmara + - Europe/Madrid + - Africa/Ceuta + - Atlantic/Canary + - Africa/Addis_Ababa + - Europe/Helsinki + - Pacific/Fiji + - Atlantic/Stanley + - Pacific/Chuuk + - Pacific/Pohnpei + - Pacific/Kosrae + - Atlantic/Faroe + - Europe/Paris + - Africa/Libreville + - Europe/London + - America/Grenada + - Asia/Tbilisi + - America/Cayenne + - Europe/Guernsey + - Africa/Accra + - Europe/Gibraltar + - America/Godthab + - America/Danmarkshavn + - America/Scoresbysund + - America/Thule + - Africa/Banjul + - Africa/Conakry + - America/Guadeloupe + - Africa/Malabo + - Europe/Athens + - Atlantic/South_Georgia + - America/Guatemala + - Pacific/Guam + - Africa/Bissau + - America/Guyana + - Asia/Hong_Kong + - America/Tegucigalpa + - Europe/Zagreb + - America/Port-au-Prince + - Europe/Budapest + - Asia/Jakarta + - Asia/Pontianak + - Asia/Makassar + - Asia/Jayapura + - Europe/Dublin + - Asia/Jerusalem + - Europe/Isle_of_Man + - Asia/Kolkata + - Indian/Chagos + - Asia/Baghdad + - Asia/Tehran + - Atlantic/Reykjavik + - Europe/Rome + - Europe/Jersey + - America/Jamaica + - Asia/Amman + - Asia/Tokyo + - Africa/Nairobi + - Asia/Bishkek + - Asia/Phnom_Penh + - Pacific/Tarawa + - Pacific/Enderbury + - Pacific/Kiritimati + - Indian/Comoro + - America/St_Kitts + - Asia/Pyongyang + - Asia/Seoul + - Asia/Kuwait + - America/Cayman + - Asia/Almaty + - Asia/Qyzylorda + - Asia/Aqtobe + - Asia/Aqtau + - Asia/Oral + - Asia/Vientiane + - Asia/Beirut + - America/St_Lucia + - Europe/Vaduz + - Asia/Colombo + - Africa/Monrovia + - Africa/Maseru + - Europe/Vilnius + - Europe/Luxembourg + - Europe/Riga + - Africa/Tripoli + - Africa/Casablanca + - Europe/Monaco + - Europe/Chisinau + - Europe/Podgorica + - America/Marigot + - Indian/Antananarivo + - Pacific/Majuro + - Pacific/Kwajalein + - Europe/Skopje + - Africa/Bamako + - Asia/Rangoon + - Asia/Ulaanbaatar + - Asia/Hovd + - Asia/Choibalsan + - Asia/Macau + - Pacific/Saipan + - America/Martinique + - Africa/Nouakchott + - America/Montserrat + - Europe/Malta + - Indian/Mauritius + - Indian/Maldives + - Africa/Blantyre + - America/Mexico_City + - America/Cancun + - America/Merida + - America/Monterrey + - America/Matamoros + - America/Mazatlan + - America/Chihuahua + - America/Ojinaga + - America/Hermosillo + - America/Tijuana + - America/Santa_Isabel + - America/Bahia_Banderas + - Asia/Kuala_Lumpur + - Asia/Kuching + - Africa/Maputo + - Africa/Windhoek + - Pacific/Noumea + - Africa/Niamey + - Pacific/Norfolk + - Africa/Lagos + - America/Managua + - Europe/Amsterdam + - Europe/Oslo + - Asia/Kathmandu + - Pacific/Nauru + - Pacific/Niue + - Pacific/Auckland + - Pacific/Chatham + - Asia/Muscat + - America/Panama + - America/Lima + - Pacific/Tahiti + - Pacific/Marquesas + - Pacific/Gambier + - Pacific/Port_Moresby + - Asia/Manila + - Asia/Karachi + - Europe/Warsaw + - America/Miquelon + - Pacific/Pitcairn + - America/Puerto_Rico + - Asia/Gaza + - Asia/Hebron + - Europe/Lisbon + - Atlantic/Madeira + - Atlantic/Azores + - Pacific/Palau + - America/Asuncion + - Asia/Qatar + - Indian/Reunion + - Europe/Bucharest + - Europe/Belgrade + - Europe/Kaliningrad + - Europe/Moscow + - Europe/Volgograd + - Europe/Samara + - Asia/Yekaterinburg + - Asia/Omsk + - Asia/Novosibirsk + - Asia/Novokuznetsk + - Asia/Krasnoyarsk + - Asia/Irkutsk + - Asia/Yakutsk + - Asia/Khandyga + - Asia/Vladivostok + - Asia/Sakhalin + - Asia/Ust-Nera + - Asia/Magadan + - Asia/Kamchatka + - Asia/Anadyr + - Africa/Kigali + - Asia/Riyadh + - Pacific/Guadalcanal + - Indian/Mahe + - Africa/Khartoum + - Europe/Stockholm + - Asia/Singapore + - Atlantic/St_Helena + - Europe/Ljubljana + - Arctic/Longyearbyen + - Europe/Bratislava + - Africa/Freetown + - Europe/San_Marino + - Africa/Dakar + - Africa/Mogadishu + - America/Paramaribo + - Africa/Juba + - Africa/Sao_Tome + - America/El_Salvador + - America/Lower_Princes + - Asia/Damascus + - Africa/Mbabane + - America/Grand_Turk + - Africa/Ndjamena + - Indian/Kerguelen + - Africa/Lome + - Asia/Bangkok + - Asia/Dushanbe + - Pacific/Fakaofo + - Asia/Dili + - Asia/Ashgabat + - Africa/Tunis + - Pacific/Tongatapu + - Europe/Istanbul + - America/Port_of_Spain + - Pacific/Funafuti + - Asia/Taipei + - Africa/Dar_es_Salaam + - Europe/Kiev + - Europe/Uzhgorod + - Europe/Zaporozhye + - Europe/Simferopol + - Africa/Kampala + - Pacific/Johnston + - Pacific/Midway + - Pacific/Wake + - America/New_York + - America/Detroit + - America/Kentucky/Louisville + - America/Kentucky/Monticello + - America/Indiana/Indianapolis + - America/Indiana/Vincennes + - America/Indiana/Winamac + - America/Indiana/Marengo + - America/Indiana/Petersburg + - America/Indiana/Vevay + - America/Chicago + - America/Indiana/Tell_City + - America/Indiana/Knox + - America/Menominee + - America/North_Dakota/Center + - America/North_Dakota/New_Salem + - America/North_Dakota/Beulah + - America/Denver + - America/Boise + - America/Phoenix + - America/Los_Angeles + - America/Anchorage + - America/Juneau + - America/Sitka + - America/Yakutat + - America/Nome + - America/Adak + - America/Metlakatla + - Pacific/Honolulu + - America/Montevideo + - Asia/Samarkand + - Asia/Tashkent + - Europe/Vatican + - America/St_Vincent + - America/Caracas + - America/Tortola + - America/St_Thomas + - Asia/Ho_Chi_Minh + - Pacific/Efate + - Pacific/Wallis + - Pacific/Apia + - Asia/Aden + - Indian/Mayotte + - Africa/Johannesburg + - Africa/Lusaka + - Africa/Harare + - UTC + description: + description: + - Set a text description of the device + required: false + default: null + type: str + hostname: + description: + - The hostname for the device. + required: false + type: raw + suboptions: + name: + default: system_host_name + required: true + type: str + description: Device Specific Variables name + location: + description: + - The physical location of the device. + required: false + default: null + type: str + latitude: + description: + - The latitude coordinate for the device's location. + required: false + default: null + type: str + longitude: + description: + - The longitude coordinate for the device's location. + required: false + default: null + type: str + range: + description: + - The range for geo-fencing feature. + required: false + default: null + type: int + enable_fencing: + description: + - Enable or disable geo-fencing. + required: false + default: null + type: bool + mobile_number: + description: + - List of mobile numbers for SMS notifications. + required: false + default: null + type: list + elements: dict + suboptions: + number: + description: + - The mobile phone number used for notification or security + purposes. + required: true + default: null + type: str + enable_sms: + description: + - Enable or disable SMS notifications. + required: false + default: false + type: bool + device_groups: + description: + - List of device groups the device belongs to. + required: false + default: null + type: list + elements: str + controller_group_list: + description: + - List of controller groups the device is associated with. + required: false + default: null + type: list + elements: int + system_ip: + description: + - The system IP address of the device. + required: false + type: raw + suboptions: + name: + default: system_system_ip + required: true + type: str + description: Device Specific Variables name + overlay_id: + description: + - The overlay ID of the device. + required: false + default: null + type: int + site_id: + description: + - The site ID of the device. + required: false + default: system_site_id + type: int + site_type: + description: + - The site type classification for the device. + required: false + default: null + type: list + elements: str + choices: + - type-1 + - type-2 + - type-3 + - cloud + - branch + - br + - spoke + port_offset: + description: + - The port offset for the device. + required: false + default: null + type: int + port_hop: + description: + - Enable or disable port hopping. + required: false + default: null + type: bool + control_session_pps: + description: + - Control session packets per second setting. + required: false + default: null + type: int + track_transport: + description: + - Enable or disable transport tracking. + required: false + default: null + type: bool + track_interface_tag: + description: + - The tag of the interface to be tracked. + required: false + default: null + type: int + console_baud_rate: + description: + - The console baud rate setting for the device. + required: false + default: null + type: str + choices: + - '1200' + - '2400' + - '4800' + - '9600' + - '19200' + - '38400' + - '57600' + - '115200' + max_omp_sessions: + description: + - The maximum number of OMP (Overlay Management Protocol) sessions. + required: false + default: null + type: int + multi_tenant: + description: + - Enable or disable multi-tenant support. + required: false + default: null + type: bool + track_default_gateway: + description: + - Enable or disable default gateway tracking. + required: false + default: null + type: bool + admin_tech_on_failure: + description: + - Enable or disable automatic generation of admin technical details + on failure. + required: false + default: null + type: bool + enable_tunnel: + description: + - Enable or disable tunnel functionality. + required: false + default: null + type: bool + idle_timeout: + description: + - The idle timeout setting for tunnels. + required: false + default: null + type: int + on_demand_idle_timeout_min: + description: + - The minimum idle timeout for on-demand tunnels. + required: false + default: null + type: int + tracker: + description: + - List of tracker configurations. + required: false + default: null + type: list + elements: dict + suboptions: + name: + description: + - Name for the Tracker + required: true + default: null + type: str + endpoint_ip: + description: + - The IP address of the endpoint to track. + required: false + default: null + type: str + endpoint_ip_transport_port: + description: + - The transport port of the endpoint IP address. + required: false + default: null + type: str + protocol: + description: + - The protocol used for the tracker (TCP or UDP). + required: false + default: null + type: str + choices: + - tcp + - udp + port: + description: + - The port number used for the tracker. + required: false + default: null + type: int + endpoint_dns_name: + description: + - The DNS name of the endpoint to track. + required: false + default: null + type: str + endpoint_api_url: + description: + - The API URL of the endpoint to track. + required: false + default: null + type: str + elements: + description: + - A list of elements to track. + required: false + default: null + type: list + elements: str + boolean: + description: + - The boolean condition to use when evaluating multiple elements. + required: false + default: or + type: str + choices: + - or + - and + threshold: + description: + - The threshold for triggering the tracker. + required: false + default: null + type: int + interval: + description: + - The interval at which the tracker checks the elements. + required: false + default: null + type: int + multiplier: + description: + - The multiplier used for determining the loss threshold. + required: false + default: null + type: int + type: + description: + - The type of tracker (interface or static route). + required: false + default: interface + type: str + choices: + - interface + - static-route + object_track: + description: + - List of object tracking configurations. + required: false + default: null + type: list + elements: dict + suboptions: + object_number: + description: + - The tracking object number. + required: true + default: null + type: int + interface: + description: + - The name of the interface to track. + required: true + default: null + type: str + sig: + description: + - The signature associated with the tracking object. + required: true + default: null + type: str + ip: + description: + - The IP address used for tracking. + required: true + default: null + type: str + mask: + description: + - The subnet mask associated with the IP address for tracking. + required: false + default: 0.0.0.0 + type: str + vpn: + description: + - The VPN instance associated with the tracking object. + required: true + default: null + type: int + object: + description: + - A list of objects related to the tracking. + required: true + default: null + type: list + elements: dict + suboptions: + number: + description: + - The unique identifier for the object. + required: true + default: null + type: int + boolean: + description: + - The boolean condition to use when evaluating multiple objects. + required: true + default: null + type: str + choices: + - or + - and + region_id: + description: + - The region ID of the device. + required: false + default: null + type: int + secondary_region: + description: + - The secondary region ID of the device. + required: false + default: null + type: int + role: + description: + - The role of the device in the network. + required: false + default: null + type: str + choices: + - edge-router + - border-router + affinity_group_number: + description: + - The affinity group number for VRF binding. + required: false + default: null + type: int + preference: + description: + - List of affinity group preferences. + required: false + default: null + type: list + elements: int + preference_auto: + description: + - Enable or disable automatic preference setting for affinity groups. + required: false + default: null + type: bool + affinity_per_vrf: + description: + - List of affinity configurations per VRF. + required: false + default: null + type: list + elements: dict + suboptions: + affinity_group_number: + description: + - The affinity group number for VRF binding. + required: false + default: null + type: int + vrf_range: + description: + - The range of VRFs associated with the affinity group. + required: false + default: null + type: str + transport_gateway: + description: + - Enable or disable the transport gateway feature. + required: false + default: null + type: bool + enable_mrf_migration: + description: + - Enable Multicast Routing Framework (MRF) migration settings. + required: false + default: null + type: str + choices: + - enabled + - enabled-from-bgp-core + migration_bgp_community: + description: + - BGP community value for MRF migration. + required: false + default: null + type: int + enable_management_region: + description: + - Enable or disable management region configuration. + required: false + default: null + type: bool + vrf: + description: + - List of VRF configurations. + required: false + default: null + type: list + elements: dict + suboptions: + vrf_id: + description: + - The VRF (VPN Routing and Forwarding) instance ID. + required: true + default: null + type: int + gateway_preference: + description: + - List of affinity group preferences for VRF + required: false + default: null + type: list + elements: int + management_gateway: + description: + - Enable or disable the management gateway feature. + required: false + default: null + type: bool + epfr: + description: + - Edge Policy-based Framework Routing (EPFR) setting. + required: false + default: null + type: str + choices: + - disabled + - aggressive + - moderate + - conservative + """ diff --git a/plugins/doc_fragments/feature_template_cisco_vpn.py b/plugins/doc_fragments/feature_template_cisco_vpn.py new file mode 100644 index 0000000..29dc1a0 --- /dev/null +++ b/plugins/doc_fragments/feature_template_cisco_vpn.py @@ -0,0 +1,1027 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + cisco_vpn: + description: Cisco VPN Feature Template configuration. + type: dict + suboptions: + vpn_id: + description: + - The unique identifier for the VPN instance (VRF). + required: false + default: null + type: int + vpn_name: + description: + - The name of the VPN instance. + required: false + default: null + type: str + tenant_vpn_id: + description: + - The tenant-specific identifier for the VPN instance, used in multi-tenant + environments. + required: false + default: null + type: int + org_name: + description: + - The name of the organization to which the VPN instance belongs. + required: false + default: null + type: str + omp_admin_distance_ipv4: + description: + - The administrative distance for IPv4 routes received over the Overlay + Management Protocol (OMP). + required: false + default: null + type: int + omp_admin_distance_ipv6: + description: + - The administrative distance for IPv6 routes received over OMP. + required: false + default: null + type: int + dns: + description: + - A list of DNS configurations for the VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + dns_addr: + description: + - The IP address of the DNS server. + required: false + default: null + type: str + role: + description: + - The role of the DNS server, either 'PRIMARY' or 'SECONDARY'. + required: false + default: primary + type: str + choices: + - primary + - secondary + dns_ipv6: + description: + - A list of DNS configurations for IPv6 within the VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + dns_addr: + description: + - The IPv6 address of the DNS server. + required: false + default: null + type: str + role: + description: + - The role of the DNS server for IPv6, optionally either 'PRIMARY' + or 'SECONDARY'. + required: false + default: primary + type: str + choices: + - primary + - secondary + layer4: + description: + - A flag indicating whether Layer 4 information is included in the + ECMP hash key. + required: false + default: null + type: bool + host: + description: + - A list of host configurations within the VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + hostname: + description: + - The hostname of the device. + required: true + default: null + type: str + ip: + description: + - A list of IP addresses associated with the hostname. + required: true + default: null + type: list + elements: str + service: + description: + - A list of service configurations associated with the VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + svc_type: + description: + - The type of service to be configured. + required: true + default: null + type: str + choices: + - FW + - IDS + - IDP + - netsvc1 + - netsvc2 + - netsvc3 + - netsvc4 + - TE + - appqoe + address: + description: + - A list of IP addresses for the service. + required: false + default: null + type: list + elements: str + interface: + description: + - The interface associated with the service. + required: false + default: null + type: str + track_enable: + description: + - Indicates whether tracking is enabled for the service. + required: false + default: null + type: bool + service_route: + description: + - A list of service route configurations for directing traffic to + services within the VPN. + required: false + default: null + type: list + elements: dict + suboptions: + prefix: + description: + - The network prefix for the service route. + required: true + default: null + type: str + vpn: + description: + - The VPN identifier where the service route is to be applied. + required: true + default: null + type: int + service: + description: + - The service associated with the route. + required: false + default: sig + type: str + choices: + - sig + route_v4: + description: + - A list of IPv4 route configurations within the VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + prefix: + description: + - The IPv4 network prefix for the static route. + required: false + default: null + type: str + next_hop: + description: + - A list of IPv4 next hops for the route. + required: false + default: null + type: list + elements: dict + suboptions: + address: + description: + - The IP address of the next hop for the route. + required: false + default: null + type: str + distance: + description: + - The administrative distance of the next hop. + required: false + default: null + type: int + next_hop_with_track: + description: + - A list of IPv4 next hops with tracking for the route. + required: false + default: null + type: list + elements: dict + suboptions: + address: + description: + - The IP address of the next hop for the route that + requires tracking. + required: false + default: null + type: str + distance: + description: + - The administrative distance of the next hop that + requires tracking. + required: false + default: null + type: int + tracker: + description: + - The tracker associated with this next hop. + required: true + default: null + type: str + route_interface: + description: + - The interface configuration for the IPv4 static route. + required: false + default: null + type: dict + elements: dict + suboptions: + interface_name: + description: + - The name of the interface used for routing. + required: true + default: null + type: str + interface_next_hop: + description: + - A list of next hops associated with the interface + for routing purposes. + required: false + default: null + type: list + elements: dict + suboptions: + address: + description: + - The IP address of the next hop for the route. + required: false + default: null + type: str + distance: + description: + - The administrative distance of the next + hop. + required: false + default: null + type: int + null0: + description: + - A flag indicating whether to route traffic to null0 for + this static route. + required: false + default: null + type: bool + distance: + description: + - The administrative distance for the static route. + required: false + default: null + type: int + vpn: + description: + - The VPN instance identifier associated with the static route. + required: false + default: null + type: int + dhcp: + description: + - A flag indicating whether DHCP is used for this static route. + required: false + default: null + type: bool + route_v6: + description: + - A list of IPv6 route configurations within the VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + prefix: + description: + - The IPv6 network prefix for the static route. + required: true + default: null + type: str + next_hop: + description: + - A list of IPv6 next hops for the route. + required: false + default: null + type: list + elements: dict + suboptions: + address: + description: + - The IPv6 address of the next hop for the route. + required: true + default: null + type: str + distance: + description: + - The administrative distance of the IPv6 next hop. + required: false + default: null + type: int + null0: + description: + - A flag indicating whether to route IPv6 traffic to null0 + for this static route. + required: false + default: null + type: bool + vpn: + description: + - The VPN instance identifier associated with the IPv6 static + route. + required: false + default: null + type: int + nat: + description: + - The type of NAT to apply for the IPv6 static route, if applicable. + required: false + default: null + type: str + choices: + - NAT64 + - NAT66 + gre_route: + description: + - A list of GRE tunnel route configurations within the VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + prefix: + description: + - The network prefix for the GRE (Generic Routing Encapsulation) + route. + required: true + default: null + type: str + vpn: + description: + - The VPN identifier where the GRE route is to be applied. + required: true + default: null + type: int + interface: + description: + - A list of interfaces associated with the GRE route. + required: false + default: null + type: list + elements: str + ipsec_route: + description: + - A list of IPSec route configurations within the VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + prefix: + description: + - The network prefix for the IPSec (Internet Protocol Security) + route. + required: true + default: null + type: str + vpn: + description: + - The VPN identifier where the IPSec route is to be applied. + required: true + default: null + type: int + interface: + description: + - A list of interfaces associated with the IPSec route. + required: false + default: null + type: list + elements: str + advertise: + description: + - A list of configurations for advertising routes via OMP within the + VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + protocol: + description: + - The protocol used for route advertisement. + required: true + default: null + type: str + choices: + - bgp + - ospf + - ospfv3 + - connected + - static + - network + - aggregate + - eigrp + - lisp + - isis + route_policy: + description: + - The route policy associated with advertisement. + required: false + default: null + type: str + protocol_sub_type: + description: + - A list of subtypes for the advertisement protocol. + required: false + default: null + type: list + elements: str + choices: + - external + prefix_list: + description: + - A list of prefix lists associated with the advertisement + settings. + required: false + default: null + type: list + elements: dict + suboptions: + prefix_entry: + description: + - The network prefix entry for the prefix list. + required: true + default: null + type: str + aggregate_only: + description: + - A flag indicating if only aggregate routes should + be considered. + required: false + default: null + type: bool + region: + description: + - The network region where the prefix list is applied. + required: false + default: null + type: str + choices: + - core + - access + ipv6_advertise: + description: + - A list of configurations for advertising IPv6 routes via OMP within + the VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + protocol: + description: + - The IPv6 protocol used for route advertisement. + required: true + default: null + type: str + choices: + - bgp + - ospf + - connected + - static + - network + - aggregate + route_policy: + description: + - The IPv6 route policy associated with advertisement. + required: false + default: null + type: str + protocol_sub_type: + description: + - A list of subtypes for the IPv6 advertisement protocol. + required: false + default: null + type: list + elements: str + choices: + - external + prefix_list: + description: + - A list of IPv6 prefix lists associated with the advertisement + settings. + required: false + default: null + type: list + elements: dict + suboptions: + prefix_entry: + description: + - The network prefix entry for the prefix list. + required: true + default: null + type: str + aggregate_only: + description: + - A flag indicating if only aggregate routes should + be considered. + required: false + default: null + type: bool + region: + description: + - The network region where the prefix list is applied. + required: false + default: null + type: str + choices: + - core + - access + pool: + description: + - A list of NAT64 pool configurations within the VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + name: + description: + - The name of the IP address pool. + required: true + default: null + type: str + start_address: + description: + - The starting IP address of the pool. + required: true + default: null + type: str + end_address: + description: + - The ending IP address of the pool. + required: true + default: null + type: str + overload: + description: + - A flag indicating whether address overload is allowed. + required: false + default: null + type: bool + leak_from_global: + description: + - A flag indicating whether leaking from the global table + is enabled. + required: true + default: null + type: bool + leak_from_global_protocol: + description: + - The protocol used for leaking from the global routing table. + required: true + default: null + type: str + choices: + - all + - static + - mobile + - connected + - rip + - odr + leak_to_global: + description: + - A flag indicating whether leaking to the global table is + enabled. + required: true + default: null + type: bool + natpool: + description: + - A list of NAT pool configurations within the VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + name: + description: + - The identifier for the NAT pool. + required: true + default: null + type: int + prefix_length: + description: + - The length of the network prefix for the NAT pool. + required: false + default: null + type: int + range_start: + description: + - The starting IP address for the NAT pool range. + required: false + default: null + type: str + range_end: + description: + - The ending IP address for the NAT pool range. + required: false + default: null + type: str + overload: + description: + - Flag indicating whether NAT overload (PAT) is enabled for + the pool. + required: false + default: 'true' + type: str + choices: + - 'true' + - 'false' + direction: + description: + - The direction (inside or outside) associated with the NAT + pool. + required: true + default: null + type: str + choices: + - inside + - outside + tracker_id: + description: + - The tracker identifier associated with the NAT pool. + required: false + default: null + type: int + static: + description: + - A list of static configurations within the VPN instance for NAT. + required: false + default: null + type: list + elements: dict + suboptions: + pool_name: + description: + - The identifier for the NAT pool associated with the static + NAT rule. + required: false + default: null + type: int + source_ip: + description: + - The original source IP address to be translated by static + NAT. + required: false + default: null + type: str + translate_ip: + description: + - The translated IP address used by static NAT. + required: false + default: null + type: str + static_nat_direction: + description: + - The direction (inside or outside) for the static NAT rule. + required: true + default: null + type: str + choices: + - inside + - outside + tracker_id: + description: + - The tracker identifier associated with the static NAT rule. + required: false + default: null + type: int + subnet_static: + description: + - A list of subnet-specific static configurations within the VPN instance + for NAT. + required: false + default: null + type: list + elements: dict + suboptions: + source_ip_subnet: + description: + - The original source IP subnet to be translated by static + NAT. + required: true + default: null + type: str + translate_ip_subnet: + description: + - The translated IP subnet used by static NAT. + required: true + default: null + type: str + prefix_length: + description: + - The prefix length for the translated IP subnet in static + NAT. + required: true + default: null + type: int + static_nat_direction: + description: + - The direction (inside or outside) for the subnet static + NAT rule. + required: true + default: null + type: str + choices: + - inside + - outside + tracker_id: + description: + - The tracker identifier associated with the subnet static + NAT rule. + required: false + default: null + type: int + port_forward: + description: + - A list of port forwarding configurations within the VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + pool_name: + description: + - The identifier for the NAT pool associated with the port + forwarding rule. + required: false + default: null + type: int + source_port: + description: + - The source port number for the port forwarding rule. + required: true + default: null + type: int + translate_port: + description: + - The destination port number to which the source port is + translated. + required: true + default: null + type: int + source_ip: + description: + - The source IP address for the port forwarding rule. + required: true + default: null + type: str + translate_ip: + description: + - The destination IP address to which the source IP is translated. + required: true + default: null + type: str + proto: + description: + - The protocol used in the port forwarding rule (TCP/UDP). + required: true + default: null + type: str + choices: + - tcp + - udp + route_import: + description: + - A list of route import configurations within the VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + protocol: + description: + - The protocol from which routes are to be imported. + required: true + default: null + type: str + choices: + - static + - connected + - bgp + - ospf + protocol_sub_type: + description: + - The list of subtypes for the import protocol. + required: true + default: null + type: list + elements: str + choices: + - external + route_policy: + description: + - The route policy that specifies the conditions for route + import. + required: false + default: null + type: str + redistribute: + description: + - A list of redistribute configurations that define how routes + from other protocols are imported. + required: false + default: null + type: list + elements: dict + suboptions: + protocol: + description: + - The protocol from which routes are to be redistributed. + required: true + default: null + type: str + choices: + - bgp + - eigrp + - ospf + route_policy: + description: + - The route policy that specifies the conditions for + route redistribution. + required: false + default: null + type: str + route_import_from: + description: + - A list of configurations specifying routes to import from other + sources into the VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + source_vpn: + description: + - The VPN instance (VRF) from which routes are to be imported. + required: true + default: null + type: int + protocol: + description: + - The routing protocol from which routes are to be imported. + required: true + default: null + type: str + choices: + - static + - connected + - bgp + - ospf + - eigrp + protocol_sub_type: + description: + - The list of protocol subtypes for route importation. + required: true + default: null + type: list + elements: str + choices: + - external + route_policy: + description: + - The route policy that specifies the criteria for route importation. + required: false + default: null + type: str + redistribute: + description: + - A list of route redistribution configurations specifying + how routes from other protocols are imported. + required: false + default: null + type: list + elements: dict + suboptions: + protocol: + description: + - The protocol from which routes are to be redistributed + into the local routing table. + required: true + default: null + type: str + choices: + - bgp + - eigrp + - ospf + route_policy: + description: + - The route policy that defines the conditions for + route redistribution. + required: false + default: null + type: str + route_export: + description: + - A list of route export configurations within the VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + protocol: + description: + - The routing protocol to which routes are to be exported. + required: true + default: null + type: str + choices: + - static + - connected + - bgp + - eigrp + - ospf + protocol_sub_type: + description: + - The list of protocol subtypes for route exportation. + required: true + default: null + type: list + elements: str + choices: + - external + route_policy: + description: + - The route policy that specifies the criteria for route exportation. + required: false + default: null + type: str + redistribute: + description: + - A list of route redistribution configurations specifying + how routes from other protocols are exported. + required: false + default: null + type: list + elements: dict + suboptions: + protocol: + description: + - The protocol from which routes are to be redistributed + out of the local routing table. + required: true + default: null + type: str + choices: + - bgp + - ospf + route_policy: + description: + - The route policy that defines the conditions for + route redistribution. + required: false + default: null + type: str + """ diff --git a/plugins/doc_fragments/feature_template_cisco_vpn_interface.py b/plugins/doc_fragments/feature_template_cisco_vpn_interface.py new file mode 100644 index 0000000..792a08e --- /dev/null +++ b/plugins/doc_fragments/feature_template_cisco_vpn_interface.py @@ -0,0 +1,1179 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + cisco_vpn_interface: + description: Cisco VPN Interface Feature Template configuration + type: dict + suboptions: + if_name: + description: + - The name of the interface. + required: false + default: null + type: str + interface_description: + description: + - A description for the interface. + required: false + default: null + type: str + poe: + description: + - Power over Ethernet setting for the interface. True if enabled, + False otherwise. + required: false + default: null + type: bool + ipv4_address: + description: + - The primary IPv4 address assigned to the interface. + required: false + default: null + type: str + secondary_ipv4_address: + description: + - A list of secondary IPv4 addresses assigned to the interface. + required: false + default: null + type: list + elements: dict + suboptions: + address: + description: + - IPv4 address with CIDR notation for the secondary interface. + required: false + default: null + type: str + dhcp_ipv4_client: + description: + - Whether DHCP client is enabled on the interface for IPv4 addressing. + True if enabled, False otherwise. + required: false + default: null + type: bool + dhcp_distance: + description: + - Administrative distance for DHCP routes on the interface. + required: false + default: null + type: int + ipv6_address: + description: + - The primary IPv6 address assigned to the interface. + required: false + default: null + type: str + dhcp_ipv6_client: + description: + - Whether DHCP client is enabled on the interface for IPv6 addressing. + True if enabled, False otherwise. + required: false + default: null + type: bool + secondary_ipv6_address: + description: + - A list of secondary IPv6 addresses assigned to the interface. + required: false + default: null + type: list + elements: dict + suboptions: + address: + description: + - IPv6 address with CIDR notation for the secondary interface. + required: false + default: null + type: str + access_list_ipv4: + description: + - A list of IPv4 access control lists (ACLs) applied to the interface. + required: false + default: null + type: list + elements: dict + suboptions: + direction: + description: + - Direction of the traffic flow for applying the ACL ('in' + or 'out'). + required: true + default: null + type: str + choices: + - in + - out + acl_name: + description: + - Name of the access control list. + required: true + default: null + type: str + dhcp_helper: + description: + - A list of DHCP helper addresses configured on the interface. + required: false + default: null + type: list + elements: str + dhcp_helper_v6: + description: + - A list of DHCPv6 helper configurations applied to the interface. + required: false + default: null + type: list + elements: dict + suboptions: + address: + description: + - IPv6 address of the DHCP server or relay. + required: true + default: null + type: str + vpn: + description: + - Optional VPN ID where the DHCP helper is configured. + required: false + default: null + type: int + tracker: + description: + - A list of tracker identifiers associated with the interface. + required: false + default: null + type: list + elements: str + auto_bandwidth_detect: + description: + - Whether automatic bandwidth detection is enabled on the interface. + True if enabled, False otherwise. + required: false + default: null + type: bool + iperf_server: + description: + - The IP address of the iPerf server used for performance testing + from this interface. + required: false + default: null + type: str + nat: + description: + - Indicates whether Network Address Translation (NAT) is enabled on + the interface. + required: false + default: null + type: bool + nat_choice: + description: + - The type of NAT configured on the interface, if applicable. + required: false + default: null + type: str + choices: + - Interface + - Pool + - Loopback + udp_timeout: + description: + - The timeout value in seconds for UDP connections through the NAT + on this interface. + required: false + default: null + type: int + tcp_timeout: + description: + - The timeout value in seconds for TCP connections through the NAT + on this interface. + required: false + default: null + type: int + nat_range_start: + description: + - The starting IP address in the range used for NAT on this interface. + required: false + default: null + type: str + nat_range_end: + description: + - The ending IP address in the range used for NAT on this interface. + required: false + default: null + type: str + overload: + description: + - Indicates if NAT overload (PAT - Port Address Translation) is enabled. + required: false + default: null + type: bool + loopback_interface: + description: + - The associated loopback interface, if any, for the VPN interface. + required: false + default: null + type: str + prefix_length: + description: + - The prefix length for the interface's IP address, indicating the + size of the subnet. + required: false + default: null + type: int + enable: + description: + - Indicates whether the interface is enabled or disabled. + required: false + default: null + type: bool + nat64: + description: + - Indicates whether NAT64 is enabled on the interface, allowing IPv6 + addresses to communicate with IPv4 services. + required: false + default: null + type: bool + nat66: + description: + - Indicates whether NAT66 is enabled on the interface, translating + IPv6 addresses into IPv6 addresses. + required: false + default: null + type: bool + static_nat66: + description: + - List of static NAT66 entries for translating IPv6 addresses into + other IPv6 addresses. + required: false + default: null + type: list + elements: dict + suboptions: + source_prefix: + description: + - IPv6 network prefix that is to be translated. + required: true + default: null + type: str + translated_source_prefix: + description: + - IPv6 network prefix to which the source prefix is translated. + required: true + default: null + type: str + source_vpn_id: + description: + - VPN ID associated with the source network prefix. + required: false + default: null + type: int + static: + description: + - List of static NAT entries for configuring one-to-one address mappings. + required: false + default: null + type: list + elements: dict + suboptions: + source_ip: + description: + - IPv4 address of the source IP for static NAT. + required: true + default: null + type: str + translate_ip: + description: + - IPv4 address used for translation in static NAT. + required: true + default: null + type: str + static_nat_direction: + description: + - Direction of static NAT mapping ('inside' or 'outside'). + required: false + default: inside + type: str + choices: + - inside + - outside + source_vpn: + description: + - VPN ID associated with the source IP for static NAT. + required: false + default: null + type: int + static_port_forward: + description: + - List of static port forwarding entries for the interface. + required: false + default: null + type: list + elements: dict + suboptions: + source_ip: + description: + - IPv4 address of the source IP for port forwarding. + required: true + default: null + type: str + translate_ip: + description: + - IPv4 address used for translation in port forwarding. + required: true + default: null + type: str + static_nat_direction: + description: + - Direction of port forwarding mapping ('inside' or 'outside'). + required: false + default: inside + type: str + choices: + - inside + - outside + source_port: + description: + - Source port number for port forwarding. + required: false + default: null + type: int + translate_port: + description: + - Translated port number for port forwarding. + required: false + default: null + type: int + proto: + description: + - Protocol used for port forwarding (TCP/UDP). + required: true + default: null + type: str + choices: + - tcp + - udp + source_vpn: + description: + - VPN ID associated with the source IP for port forwarding. + required: false + default: null + type: int + enable_core_region: + description: + - Indicates if the interface is part of the core network region for + centralized services. + required: false + default: null + type: bool + core_region: + description: + - Configuration details for the core region. + required: false + default: null + type: str + choices: + - core + - core-shared + secondary_region: + description: + - Configuration details for a secondary region. + required: false + default: null + type: str + choices: + - 'off' + - secondary-only + - secondary-shared + tloc_encapsulation: + description: + - Transport Location (TLOC) encapsulation settings. + required: false + default: null + type: list + elements: dict + suboptions: + encap: + description: + - Type of encapsulation used for the VPN tunnel (GRE/IPsec). + required: true + default: null + type: str + choices: + - gre + - ipsec + preference: + description: + - Preference value for the encapsulation type (lower values + have higher priority). + required: false + default: null + type: int + weight: + description: + - Weight for the encapsulation type used in load balancing + decisions. + required: false + default: null + type: int + border: + description: + - Defines if the interface is at the border of a network segment. + required: false + default: null + type: bool + per_tunnel_qos: + description: + - Enable or disable per-tunnel Quality of Service (QoS). + required: false + default: null + type: bool + per_tunnel_qos_aggregator: + description: + - Enable or disable per-tunnel QoS aggregator. + required: false + default: null + type: bool + mode: + description: + - Defines the operating mode for the interface. + required: false + default: null + type: str + choices: + - hub + - spoke + tunnels_bandwidth: + description: + - Specifies the total bandwidth available across all tunnels. + required: false + default: null + type: int + group: + description: + - Identifies the group or groups the interface belongs to. + required: false + default: null + type: list + elements: int + value: + description: + - The value field often corresponds to a specific attribute or setting, + such as color in this context. + required: false + default: null + type: str + choices: + - default + - mpls + - metro-ethernet + - biz-internet + - public-internet + - lte + - 3g + - red + - green + - blue + - gold + - silver + - bronze + - custom1 + - custom2 + - custom3 + - private1 + - private2 + - private3 + - private4 + - private5 + - private6 + max_control_connections: + description: + - Maximum number of control connections that can be established on + the interface. + required: false + default: null + type: int + control_connections: + description: + - Enables or disables control connections on the interface. + required: false + default: null + type: bool + vbond_as_stun_server: + description: + - Configures the vBond orchestrator to act as a STUN server for the + interface. + required: false + default: null + type: bool + exclude_controller_group_list: + description: + - List of controller groups to exclude from connections. + required: false + default: null + type: list + elements: int + vmanage_connection_preference: + description: + - Preference value for establishing vManage connections. + required: false + default: null + type: int + port_hop: + description: + - Enables or disables port hopping for the interface to evade port + blocking. + required: false + default: null + type: bool + restrict: + description: + - Indicates whether the interface color is restricted for use. + required: false + default: null + type: bool + dst_ip: + description: + - Destination IP address for GRE (Generic Routing Encapsulation) tunnel + extension. + required: false + default: null + type: str + carrier: + description: + - Specifies the carrier information for the tunnel interface. + required: false + default: null + type: str + choices: + - default + - carrier1 + - carrier2 + - carrier3 + - carrier4 + - carrier5 + - carrier6 + - carrier7 + - carrier8 + nat_refresh_interval: + description: + - Interval in seconds to refresh NAT (Network Address Translation) + mappings. + required: false + default: null + type: int + hello_interval: + description: + - Time interval in seconds between successive hello packets sent over + the tunnel interface. + required: false + default: null + type: int + hello_tolerance: + description: + - Time in seconds to wait before declaring a neighbor down due to + missing hello packets. + required: false + default: null + type: int + bind: + description: + - Interface or IP address to which the tunnel interface is bound. + required: false + default: null + type: str + last_resort_circuit: + description: + - Marks the interface as a last resort circuit for traffic to fall + back to. + required: false + default: null + type: bool + low_bandwidth_link: + description: + - Indicates if the link is considered a low bandwidth link. + required: false + default: null + type: bool + tunnel_tcp_mss_adjust: + description: + - Adjusts the Maximum Segment Size (MSS) value for TCP connections + over the tunnel. + required: false + default: null + type: int + clear_dont_fragment: + description: + - Enables or disables the clearing of the 'Don't Fragment' (DF) bit + in the IP header. + required: false + default: null + type: bool + propagate_sgt: + description: + - Enables or disables the propagation of Security Group Tags (SGTs) + across the tunnel interface. + required: false + default: null + type: bool + network_broadcast: + description: + - Allows or disallows network broadcast traffic through the tunnel + interface. + required: false + default: null + type: bool + all: + description: + - Permits or denies all services through the tunnel interface. + required: false + default: null + type: bool + bgp: + description: + - Allows or disallows Border Gateway Protocol (BGP) traffic through + the tunnel interface. + required: false + default: null + type: bool + dhcp: + description: + - Enables or disables Dynamic Host Configuration Protocol (DHCP) on + the tunnel interface. + required: false + default: null + type: bool + dns: + description: + - Allows or disallows Domain Name System (DNS) queries through the + tunnel interface. + required: false + default: null + type: bool + icmp: + description: + - Enables or disables Internet Control Message Protocol (ICMP) for + ping and traceroute through the tunnel interface. + required: false + default: null + type: bool + sshd: + description: + - Allows or disallows Secure Shell (SSH) daemon access through the + tunnel interface. + required: false + default: null + type: bool + netconf: + description: + - Enables or disables NETCONF protocol support on the tunnel interface. + required: false + default: null + type: bool + ntp: + description: + - Allows or disallows Network Time Protocol (NTP) synchronization + through the tunnel interface. + required: false + default: null + type: bool + ospf: + description: + - Permits or denies Open Shortest Path First (OSPF) routing protocol + traffic through the tunnel interface. + required: false + default: null + type: bool + stun: + description: + - Enables or disables Session Traversal Utilities for NAT (STUN) on + the tunnel interface. + required: false + default: null + type: bool + snmp: + description: + - Allows or disallows Simple Network Management Protocol (SNMP) through + the tunnel interface. + required: false + default: null + type: bool + https: + description: + - Permits or denies HTTPS traffic through the tunnel interface. + required: false + default: null + type: bool + media_type: + description: + - Specifies the media type used by the interface, such as copper or + fiber. + required: false + default: null + type: str + choices: + - auto-select + - rj45 + - sfp + intrf_mtu: + description: + - Sets the Maximum Transmission Unit (MTU) size for the interface. + required: false + default: null + type: int + mtu: + description: + - Specifies the MTU size for the tunnel or logical interface. + required: false + default: null + type: int + tcp_mss_adjust: + description: + - Adjusts the TCP Maximum Segment Size (MSS) value for connections + over the interface. + required: false + default: null + type: int + tloc_extension: + description: + - Defines the Transport Location (TLOC) extension for the interface. + required: false + default: null + type: str + load_interval: + description: + - Sets the time interval in seconds for calculating interface load + statistics. + required: false + default: null + type: int + src_ip: + description: + - Source IP address for GRE tunnel extension. + required: false + default: null + type: str + xconnect: + description: + - Cross-connect identifier for the GRE tunnel extension. + required: false + default: null + type: str + mac_address: + description: + - Specifies the MAC address for the interface. + required: false + default: null + type: str + speed: + description: + - Defines the speed of the interface, such as 10Mbps, 100Mbps, or + 1Gbps. + required: false + default: null + type: str + choices: + - '10' + - '100' + - '1000' + - '2500' + - '10000' + duplex: + description: + - Sets the duplex mode for the interface, such as full or half duplex. + required: false + default: null + type: str + choices: + - full + - half + - auto + shutdown: + description: + - Enables or disables (shuts down) the interface. + required: false + default: false + type: bool + arp_timeout: + description: + - Time in seconds before an ARP cache entry is timed out. + required: false + default: null + type: int + autonegotiate: + description: + - Enables or disables autonegotiation of speed and duplex settings + on the interface. + required: false + default: null + type: bool + ip_directed_broadcast: + description: + - Allows or disallows IP directed broadcasts on the interface. + required: false + default: null + type: bool + icmp_redirect_disable: + description: + - Enables or disables ICMP redirect messages on the interface. + required: false + default: null + type: bool + qos_adaptive: + description: + - Activates or deactivates adaptive QoS on the interface. + required: false + default: null + type: bool + period: + description: + - Time period in seconds for measuring and adapting QoS settings. + required: false + default: null + type: int + bandwidth_down: + description: + - Specifies the downstream bandwidth in Kbps for adaptive QoS calculations. + required: false + default: null + type: int + dmin: + description: + - Specifies the minimum downstream bandwidth in Kbps for adaptive + QoS. + required: false + default: null + type: int + dmax: + description: + - Specifies the maximum downstream bandwidth in Kbps for adaptive + QoS. + required: false + default: null + type: int + bandwidth_up: + description: + - Specifies the upstream bandwidth in Kbps for adaptive QoS calculations. + required: false + default: null + type: int + umin: + description: + - Specifies the minimum upstream bandwidth in Kbps for adaptive QoS. + required: false + default: null + type: int + umax: + description: + - Specifies the maximum upstream bandwidth in Kbps for adaptive QoS. + required: false + default: null + type: int + shaping_rate: + description: + - Defines the traffic shaping rate for the interface. + required: false + default: null + type: int + qos_map: + description: + - Associates a QoS map with the interface for traffic classification + and prioritization. + required: false + default: null + type: str + qos_map_vpn: + description: + - Associates a QoS map with a VPN for traffic classification and prioritization + within the VPN. + required: false + default: null + type: str + service_provider: + description: + - Identifies the service provider associated with the interface. + required: false + default: null + type: str + bandwidth_upstream: + description: + - Specifies the upstream bandwidth in Kbps available on the interface. + required: false + default: null + type: int + bandwidth_downstream: + description: + - Specifies the downstream bandwidth in Kbps available on the interface. + required: false + default: null + type: int + block_non_source_ip: + description: + - Enables or disables blocking of traffic with non-matching source + IP addresses. + required: false + default: null + type: bool + rule_name: + description: + - Specifies the name of the rewrite rule applied to the interface. + required: false + default: null + type: str + access_list_ipv6: + description: + - Defines a list of access control entries for IPv6 traffic filtering. + required: false + default: null + type: list + elements: dict + suboptions: + direction: + description: + - Direction of the traffic flow for applying the ACL ('in' + or 'out'). + required: true + default: null + type: str + choices: + - in + - out + acl_name: + description: + - Name of the access control list. + required: true + default: null + type: str + ip: + description: + - A list of IP configurations for Address Resolution Protocol (ARP) + settings. + required: false + default: null + type: list + elements: dict + suboptions: + addr: + description: + - IPv4 address for the interface. + required: true + default: null + type: str + mac: + description: + - MAC address associated with the IPv4 address. + required: true + default: null + type: str + vrrp: + description: + - A list of Virtual Router Redundancy Protocol (VRRP) configurations + for IPv4. + required: false + default: null + type: list + elements: dict + suboptions: + grp_id: + description: + - VRRP group ID. + required: true + default: null + type: int + priority: + description: + - Priority value for the VRRP group (higher values take precedence). + required: false + default: null + type: int + timer: + description: + - VRRP advertisement interval timer in milliseconds. + required: false + default: null + type: int + track_omp: + description: + - Flag to track Overlay Management Protocol (OMP) session + state. + required: false + default: null + type: bool + track_prefix_list: + description: + - Name of the prefix-list used for tracking specific routes. + required: false + default: null + type: str + address: + description: + - Virtual IP address used by the VRRP group. + required: false + default: null + type: str + ipv4_secondary: + description: + - List of secondary IPv4 addresses for the VRRP group. + required: false + default: null + type: list + elements: dict + suboptions: + address: + description: + - IPv4 address for the secondary interface. + required: true + default: null + type: str + tloc_change_pref: + description: + - Flag to change preference based on TLOC status. + required: false + default: null + type: bool + value: + description: + - VRRP value to determine the primary node for the VRRP group. + required: true + default: null + type: int + tracking_object: + description: + - List of tracking objects associated with the VRRP configuration. + required: false + default: null + type: list + elements: dict + suboptions: + name: + description: + - Unique identifier for the tracking object. + required: true + default: null + type: int + track_action: + description: + - Action to take when the tracked object state changes + (e.g., decrement priority or shutdown). + required: false + default: Decrement + type: str + choices: + - Decrement + - Shutdown + decrement: + description: + - Value by which to decrement the VRRP priority when + the tracked object is down. + required: true + default: null + type: int + ipv6_vrrp: + description: + - A list of Virtual Router Redundancy Protocol (VRRP) configurations + for IPv6. + required: false + default: null + type: list + elements: dict + suboptions: + grp_id: + description: + - IPv6 VRRP group ID. + required: true + default: null + type: int + priority: + description: + - Priority value for the IPv6 VRRP group (higher values take + precedence). + required: false + default: null + type: int + timer: + description: + - IPv6 VRRP advertisement interval timer in milliseconds. + required: false + default: null + type: int + track_omp: + description: + - Flag to track Overlay Management Protocol (OMP) session + state for IPv6. + required: false + default: null + type: bool + track_prefix_list: + description: + - Name of the IPv6 prefix-list used for tracking specific + routes. + required: false + default: null + type: str + ipv6: + description: + - List of IPv6 configurations associated with the VRRP group. + required: false + default: null + type: list + elements: dict + suboptions: + ipv6_link_local: + description: + - IPv6 link-local address for the interface. + required: true + default: null + type: str + prefix: + description: + - Optional IPv6 prefix for the interface, with CIDR + notation. + required: false + default: null + type: str + enable_sgt_propagation: + description: + - Enables or disables Security Group Tag (SGT) propagation. + required: false + default: null + type: bool + security_group_tag: + description: + - Specifies a static Security Group Tag (SGT) for the interface. + required: false + default: null + type: int + trusted: + description: + - Marks the interface as trusted or untrusted for TrustSec. + required: false + default: null + type: bool + enable_sgt_authorization_and_forwarding: + description: + - Enables or disables Security Group Tag (SGT) authorization and forwarding. + required: false + default: null + type: bool + enable_sgt_enforcement: + description: + - Activates or deactivates Security Group Tag (SGT) enforcement. + required: false + default: null + type: bool + enforcement_sgt: + description: + - Specifies the Security Group Tag (SGT) to be enforced on the interface. + required: false + default: null + type: int + """ diff --git a/plugins/doc_fragments/feature_template_omp_vsmart.py b/plugins/doc_fragments/feature_template_omp_vsmart.py new file mode 100644 index 0000000..73a48e3 --- /dev/null +++ b/plugins/doc_fragments/feature_template_omp_vsmart.py @@ -0,0 +1,87 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + omp_vsmart: + description: Overlay Management Protocol (OMP) settings for vSmart controller + type: dict + suboptions: + graceful_restart: + description: + - Enable or disable graceful restart for the OMP session + required: false + default: null + type: bool + send_path_limit: + description: + - The maximum number of paths that can be sent to a TLOC + required: false + default: null + type: int + send_backup_paths: + description: + - Enable or disable sending additional backup paths + required: false + default: null + type: bool + discard_rejected: + description: + - Discard routes that are rejected by policy instead of marking them + as rejected + required: false + default: null + type: bool + shutdown: + description: + - Enable or disable the shutdown of the OMP session + required: false + default: null + type: bool + graceful_restart_timer: + description: + - The time interval for graceful restart of OMP sessions + required: false + default: null + type: int + eor_timer: + description: + - The End of Routes (EOR) timer value + required: false + default: null + type: int + holdtime: + description: + - The hold time interval for OMP sessions + required: false + default: null + type: int + affinity_group_preference: + description: + - Filter routes based on affinity preference list + required: false + default: false + type: bool + advertisement_interval: + description: + - Interval between sending OMP route advertisements + required: false + default: null + type: int + tloc_color: + description: + - Filter routes based on TLOC color + required: false + default: false + type: bool + """ diff --git a/plugins/doc_fragments/feature_template_security_vsmart.py b/plugins/doc_fragments/feature_template_security_vsmart.py new file mode 100644 index 0000000..20a6182 --- /dev/null +++ b/plugins/doc_fragments/feature_template_security_vsmart.py @@ -0,0 +1,35 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + security_vsmart: + description: Security settings for vSmart controller + type: dict + suboptions: + protocol: + description: + - The security protocol used for control plane communication + required: false + default: null + type: str + choices: + - dtls + - tls + tls_port: + description: + - The port used for TLS communications + required: false + default: null + type: int + """ diff --git a/plugins/doc_fragments/feature_template_system_vsmart.py b/plugins/doc_fragments/feature_template_system_vsmart.py new file mode 100644 index 0000000..dc70f37 --- /dev/null +++ b/plugins/doc_fragments/feature_template_system_vsmart.py @@ -0,0 +1,743 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + system_vsmart: + description: Security settings for vSmart controller + type: dict + suboptions: + timezone: + description: + - The timezone setting for the vSmart controller + required: false + default: UTC + type: str + choices: + - Europe/Andorra + - Asia/Dubai + - Asia/Kabul + - America/Antigua + - America/Anguilla + - Europe/Tirane + - Asia/Yerevan + - Africa/Luanda + - Antarctica/McMurdo + - Antarctica/Rothera + - Antarctica/Palmer + - Antarctica/Mawson + - Antarctica/Davis + - Antarctica/Casey + - Antarctica/Vostok + - Antarctica/DumontDUrville + - Antarctica/Syowa + - America/Argentina/Buenos_Aires + - America/Argentina/Cordoba + - America/Argentina/Salta + - America/Argentina/Jujuy + - America/Argentina/Tucuman + - America/Argentina/Catamarca + - America/Argentina/La_Rioja + - America/Argentina/San_Juan + - America/Argentina/Mendoza + - America/Argentina/San_Luis + - America/Argentina/Rio_Gallegos + - America/Argentina/Ushuaia + - Pacific/Pago_Pago + - Europe/Vienna + - Australia/Lord_Howe + - Antarctica/Macquarie + - Australia/Hobart + - Australia/Currie + - Australia/Melbourne + - Australia/Sydney + - Australia/Broken_Hill + - Australia/Brisbane + - Australia/Lindeman + - Australia/Adelaide + - Australia/Darwin + - Australia/Perth + - Australia/Eucla + - America/Aruba + - Europe/Mariehamn + - Asia/Baku + - Europe/Sarajevo + - America/Barbados + - Asia/Dhaka + - Europe/Brussels + - Africa/Ouagadougou + - Europe/Sofia + - Asia/Bahrain + - Africa/Bujumbura + - Africa/Porto-Novo + - America/St_Barthelemy + - Atlantic/Bermuda + - Asia/Brunei + - America/La_Paz + - America/Kralendijk + - America/Noronha + - America/Belem + - America/Fortaleza + - America/Recife + - America/Araguaina + - America/Maceio + - America/Bahia + - America/Sao_Paulo + - America/Campo_Grande + - America/Cuiaba + - America/Santarem + - America/Porto_Velho + - America/Boa_Vista + - America/Manaus + - America/Eirunepe + - America/Rio_Branco + - America/Nassau + - Asia/Thimphu + - Africa/Gaborone + - Europe/Minsk + - America/Belize + - America/St_Johns + - America/Halifax + - America/Glace_Bay + - America/Moncton + - America/Goose_Bay + - America/Blanc-Sablon + - America/Toronto + - America/Nipigon + - America/Thunder_Bay + - America/Iqaluit + - America/Pangnirtung + - America/Resolute + - America/Atikokan + - America/Rankin_Inlet + - America/Winnipeg + - America/Rainy_River + - America/Regina + - America/Swift_Current + - America/Edmonton + - America/Cambridge_Bay + - America/Yellowknife + - America/Inuvik + - America/Creston + - America/Dawson_Creek + - America/Vancouver + - America/Whitehorse + - America/Dawson + - Indian/Cocos + - Africa/Kinshasa + - Africa/Lubumbashi + - Africa/Bangui + - Africa/Brazzaville + - Europe/Zurich + - Africa/Abidjan + - Pacific/Rarotonga + - America/Santiago + - Pacific/Easter + - Africa/Douala + - Asia/Shanghai + - Asia/Harbin + - Asia/Chongqing + - Asia/Urumqi + - Asia/Kashgar + - America/Bogota + - America/Costa_Rica + - America/Havana + - Atlantic/Cape_Verde + - America/Curacao + - Indian/Christmas + - Asia/Nicosia + - Europe/Prague + - Europe/Berlin + - Europe/Busingen + - Africa/Djibouti + - Europe/Copenhagen + - America/Dominica + - America/Santo_Domingo + - Africa/Algiers + - America/Guayaquil + - Pacific/Galapagos + - Europe/Tallinn + - Africa/Cairo + - Africa/El_Aaiun + - Africa/Asmara + - Europe/Madrid + - Africa/Ceuta + - Atlantic/Canary + - Africa/Addis_Ababa + - Europe/Helsinki + - Pacific/Fiji + - Atlantic/Stanley + - Pacific/Chuuk + - Pacific/Pohnpei + - Pacific/Kosrae + - Atlantic/Faroe + - Europe/Paris + - Africa/Libreville + - Europe/London + - America/Grenada + - Asia/Tbilisi + - America/Cayenne + - Europe/Guernsey + - Africa/Accra + - Europe/Gibraltar + - America/Godthab + - America/Danmarkshavn + - America/Scoresbysund + - America/Thule + - Africa/Banjul + - Africa/Conakry + - America/Guadeloupe + - Africa/Malabo + - Europe/Athens + - Atlantic/South_Georgia + - America/Guatemala + - Pacific/Guam + - Africa/Bissau + - America/Guyana + - Asia/Hong_Kong + - America/Tegucigalpa + - Europe/Zagreb + - America/Port-au-Prince + - Europe/Budapest + - Asia/Jakarta + - Asia/Pontianak + - Asia/Makassar + - Asia/Jayapura + - Europe/Dublin + - Asia/Jerusalem + - Europe/Isle_of_Man + - Asia/Kolkata + - Indian/Chagos + - Asia/Baghdad + - Asia/Tehran + - Atlantic/Reykjavik + - Europe/Rome + - Europe/Jersey + - America/Jamaica + - Asia/Amman + - Asia/Tokyo + - Africa/Nairobi + - Asia/Bishkek + - Asia/Phnom_Penh + - Pacific/Tarawa + - Pacific/Enderbury + - Pacific/Kiritimati + - Indian/Comoro + - America/St_Kitts + - Asia/Pyongyang + - Asia/Seoul + - Asia/Kuwait + - America/Cayman + - Asia/Almaty + - Asia/Qyzylorda + - Asia/Aqtobe + - Asia/Aqtau + - Asia/Oral + - Asia/Vientiane + - Asia/Beirut + - America/St_Lucia + - Europe/Vaduz + - Asia/Colombo + - Africa/Monrovia + - Africa/Maseru + - Europe/Vilnius + - Europe/Luxembourg + - Europe/Riga + - Africa/Tripoli + - Africa/Casablanca + - Europe/Monaco + - Europe/Chisinau + - Europe/Podgorica + - America/Marigot + - Indian/Antananarivo + - Pacific/Majuro + - Pacific/Kwajalein + - Europe/Skopje + - Africa/Bamako + - Asia/Rangoon + - Asia/Ulaanbaatar + - Asia/Hovd + - Asia/Choibalsan + - Asia/Macau + - Pacific/Saipan + - America/Martinique + - Africa/Nouakchott + - America/Montserrat + - Europe/Malta + - Indian/Mauritius + - Indian/Maldives + - Africa/Blantyre + - America/Mexico_City + - America/Cancun + - America/Merida + - America/Monterrey + - America/Matamoros + - America/Mazatlan + - America/Chihuahua + - America/Ojinaga + - America/Hermosillo + - America/Tijuana + - America/Santa_Isabel + - America/Bahia_Banderas + - Asia/Kuala_Lumpur + - Asia/Kuching + - Africa/Maputo + - Africa/Windhoek + - Pacific/Noumea + - Africa/Niamey + - Pacific/Norfolk + - Africa/Lagos + - America/Managua + - Europe/Amsterdam + - Europe/Oslo + - Asia/Kathmandu + - Pacific/Nauru + - Pacific/Niue + - Pacific/Auckland + - Pacific/Chatham + - Asia/Muscat + - America/Panama + - America/Lima + - Pacific/Tahiti + - Pacific/Marquesas + - Pacific/Gambier + - Pacific/Port_Moresby + - Asia/Manila + - Asia/Karachi + - Europe/Warsaw + - America/Miquelon + - Pacific/Pitcairn + - America/Puerto_Rico + - Asia/Gaza + - Asia/Hebron + - Europe/Lisbon + - Atlantic/Madeira + - Atlantic/Azores + - Pacific/Palau + - America/Asuncion + - Asia/Qatar + - Indian/Reunion + - Europe/Bucharest + - Europe/Belgrade + - Europe/Kaliningrad + - Europe/Moscow + - Europe/Volgograd + - Europe/Samara + - Asia/Yekaterinburg + - Asia/Omsk + - Asia/Novosibirsk + - Asia/Novokuznetsk + - Asia/Krasnoyarsk + - Asia/Irkutsk + - Asia/Yakutsk + - Asia/Khandyga + - Asia/Vladivostok + - Asia/Sakhalin + - Asia/Ust-Nera + - Asia/Magadan + - Asia/Kamchatka + - Asia/Anadyr + - Africa/Kigali + - Asia/Riyadh + - Pacific/Guadalcanal + - Indian/Mahe + - Africa/Khartoum + - Europe/Stockholm + - Asia/Singapore + - Atlantic/St_Helena + - Europe/Ljubljana + - Arctic/Longyearbyen + - Europe/Bratislava + - Africa/Freetown + - Europe/San_Marino + - Africa/Dakar + - Africa/Mogadishu + - America/Paramaribo + - Africa/Juba + - Africa/Sao_Tome + - America/El_Salvador + - America/Lower_Princes + - Asia/Damascus + - Africa/Mbabane + - America/Grand_Turk + - Africa/Ndjamena + - Indian/Kerguelen + - Africa/Lome + - Asia/Bangkok + - Asia/Dushanbe + - Pacific/Fakaofo + - Asia/Dili + - Asia/Ashgabat + - Africa/Tunis + - Pacific/Tongatapu + - Europe/Istanbul + - America/Port_of_Spain + - Pacific/Funafuti + - Asia/Taipei + - Africa/Dar_es_Salaam + - Europe/Kiev + - Europe/Uzhgorod + - Europe/Zaporozhye + - Europe/Simferopol + - Africa/Kampala + - Pacific/Johnston + - Pacific/Midway + - Pacific/Wake + - America/New_York + - America/Detroit + - America/Kentucky/Louisville + - America/Kentucky/Monticello + - America/Indiana/Indianapolis + - America/Indiana/Vincennes + - America/Indiana/Winamac + - America/Indiana/Marengo + - America/Indiana/Petersburg + - America/Indiana/Vevay + - America/Chicago + - America/Indiana/Tell_City + - America/Indiana/Knox + - America/Menominee + - America/North_Dakota/Center + - America/North_Dakota/New_Salem + - America/North_Dakota/Beulah + - America/Denver + - America/Boise + - America/Phoenix + - America/Los_Angeles + - America/Anchorage + - America/Juneau + - America/Sitka + - America/Yakutat + - America/Nome + - America/Adak + - America/Metlakatla + - Pacific/Honolulu + - America/Montevideo + - Asia/Samarkand + - Asia/Tashkent + - Europe/Vatican + - America/St_Vincent + - America/Caracas + - America/Tortola + - America/St_Thomas + - Asia/Ho_Chi_Minh + - Pacific/Efate + - Pacific/Wallis + - Pacific/Apia + - Asia/Aden + - Indian/Mayotte + - Africa/Johannesburg + - Africa/Lusaka + - Africa/Harare + - UTC + host_name: + description: + - The hostname for the vSmart controller + required: false + type: raw + suboptions: + name: + default: system_host_name + required: true + type: str + description: Device Specific Variables name + dual_stack_ipv6: + description: + - Enable Dual Stack IPv6 Default + required: false + type: raw + suboptions: + name: + default: system_ipv6-strict-control + required: true + type: str + description: Device Specific Variables name + description: + description: + - Set a text description of the device + required: false + default: null + type: str + location: + description: + - A description of the physical location of the vSmart controller + required: false + default: null + type: str + system_tunnel_mtu: + description: + - MTU size for system tunnels + required: false + default: null + type: int + latitude: + description: + - Geographical latitude of the vSmart controller + required: false + default: null + type: int + longitude: + description: + - Geographical longitude of the vSmart controller + required: false + default: null + type: int + device_groups: + description: + - Device group names for the vSmart controller + required: false + default: null + type: list + elements: str + system_ip: + description: + - System IP address for the vSmart controller + required: false + type: raw + suboptions: + name: + default: system_system_ip + required: true + type: str + description: Device Specific Variables name + site_id: + description: + - Site ID for the vSmart controller + required: false + type: raw + suboptions: + name: + default: system_site_id + required: true + type: str + description: Device Specific Variables name + overlay_id: + description: + - Overlay ID for the vSmart controller + required: false + default: null + type: int + topology: + description: + - Set the topology + required: false + default: null + type: list + elements: str + choices: + - hub-and-spoke + port_offset: + description: + - Port offset for port hopping + required: false + default: null + type: int + port_hop: + description: + - Enable or disable port hopping + required: false + default: null + type: bool + control_session_pps: + description: + - Control session packets per second limit + required: false + default: null + type: int + controller_group_id: + description: + - Group ID for the vSmart controller + required: false + default: null + type: int + track_transport: + description: + - Enable or disable tracking of transport connections + required: false + default: true + type: bool + track_default_gateway: + description: + - Enable or disable tracking of the default gateway + required: false + default: true + type: bool + iptables_enable: + description: + - Enable or disable iptables for security + required: false + default: true + type: bool + admin_tech_on_failure: + description: + - Enable automatic generation of tech-support file on failure + required: false + default: true + type: bool + idle_timeout: + description: + - Idle timeout in minutes for user sessions + required: false + default: null + type: int + dns_cache_timeout: + description: + - DNS cache timeout in minutes + required: false + default: null + type: int + region_list_id: + description: + - Configure a list of region ID + required: false + default: null + type: int + management_region: + description: + - Management Region + required: false + default: null + type: bool + compatible: + description: + - Configure compatible TLOC color + required: false + default: null + type: list + elements: dict + suboptions: + color_1: + description: + - First TLOC color in comparsion + required: false + default: null + type: str + choices: + - default + - mpls + - metro-ethernet + - biz-internet + - public-internet + - lte + - 3g + - red + - green + - blue + - gold + - silver + - bronze + - custom1 + - custom2 + - custom3 + - private1 + - private2 + - private3 + - private4 + - private5 + - private6 + color_2: + description: + - Second TLOC color in comparsion + required: false + default: null + type: str + choices: + - default + - mpls + - metro-ethernet + - biz-internet + - public-internet + - lte + - 3g + - red + - green + - blue + - gold + - silver + - bronze + - custom1 + - custom2 + - custom3 + - private1 + - private2 + - private3 + - private4 + - private5 + - private6 + incompatible: + description: + - Configure incompatible TLOC color + required: false + default: null + type: list + elements: dict + suboptions: + color_1: + description: + - First TLOC color in comparsion + required: false + default: null + type: str + choices: + - default + - mpls + - metro-ethernet + - biz-internet + - public-internet + - lte + - 3g + - red + - green + - blue + - gold + - silver + - bronze + - custom1 + - custom2 + - custom3 + - private1 + - private2 + - private3 + - private4 + - private5 + - private6 + color_2: + description: + - Second TLOC color in comparsion + required: false + default: null + type: str + choices: + - default + - mpls + - metro-ethernet + - biz-internet + - public-internet + - lte + - 3g + - red + - green + - blue + - gold + - silver + - bronze + - custom1 + - custom2 + - custom3 + - private1 + - private2 + - private3 + - private4 + - private5 + - private6 + """ diff --git a/plugins/doc_fragments/feature_template_vpn_vsmart.py b/plugins/doc_fragments/feature_template_vpn_vsmart.py new file mode 100644 index 0000000..6b35787 --- /dev/null +++ b/plugins/doc_fragments/feature_template_vpn_vsmart.py @@ -0,0 +1,222 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + vpn_vsmart: + description: vSmart VPN Feature Template configuration. + type: dict + suboptions: + vpn_id: + description: + - The unique identifier for the VPN, only 0 and 512 are allowed on + vsmart + required: true + default: null + type: str + choices: + - '0' + - '512' + name: + description: + - The name of the VPN. + required: false + default: null + type: str + dns: + description: + - A list of DNS configurations for the VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + dns_addr: + description: + - The IP address of the DNS server. + required: false + default: null + type: str + role: + description: + - The role of the DNS server, either 'PRIMARY' or 'SECONDARY'. + required: true + default: null + type: str + choices: + - primary + - secondary + host: + description: + - Static DNS mapping + required: false + default: null + type: list + elements: dict + suboptions: + hostname: + description: + - The hostname of the device. + required: true + default: null + type: str + ip: + description: + - A list of IP addresses associated with the hostname. + required: true + default: null + type: list + elements: str + route_v4: + description: + - A list of IPv4 route configurations within the VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + prefix: + description: + - The IPv4 network prefix for the static route. + required: false + default: null + type: str + next_hop: + description: + - A list of IPv4 next hops for the route. + required: false + default: null + type: list + elements: dict + suboptions: + address: + description: + - The IP address of the next hop for the route. + required: false + default: null + type: str + distance: + description: + - The administrative distance of the next hop. + required: false + default: null + type: int + route_interface: + description: + - The interface configuration for the IPv4 static route. + required: false + default: null + type: dict + elements: dict + suboptions: + interface_name: + description: + - The name of the interface used for routing. + required: true + default: null + type: str + interface_next_hop: + description: + - A list of next hops associated with the interface + for routing purposes. + required: false + default: null + type: list + elements: dict + suboptions: + address: + description: + - The IP address of the next hop for the route. + required: false + default: null + type: str + distance: + description: + - The administrative distance of the next + hop. + required: false + default: null + type: int + null0: + description: + - A flag indicating whether to route traffic to null0 for + this static route. + required: false + default: null + type: bool + distance: + description: + - The administrative distance for the static route. + required: false + default: null + type: int + vpn: + description: + - The VPN instance identifier associated with the static route. + required: false + default: null + type: int + route_v6: + description: + - A list of IPv6 route configurations within the VPN instance. + required: false + default: null + type: list + elements: dict + suboptions: + prefix: + description: + - The IPv6 network prefix for the static route. + required: true + default: null + type: str + next_hop: + description: + - A list of IPv6 next hops for the route. + required: false + default: null + type: list + elements: dict + suboptions: + address: + description: + - The IPv6 address of the next hop for the route. + required: true + default: null + type: str + distance: + description: + - The administrative distance of the IPv6 next hop. + required: false + default: null + type: int + null0: + description: + - A flag indicating whether to route IPv6 traffic to null0 + for this static route. + required: false + default: null + type: bool + distance: + description: + - The administrative distance for the static route. + required: false + default: null + type: int + vpn: + description: + - The VPN instance identifier associated with the static route. + required: false + default: null + type: int + """ diff --git a/plugins/doc_fragments/feature_template_vpn_vsmart_interface.py b/plugins/doc_fragments/feature_template_vpn_vsmart_interface.py new file mode 100644 index 0000000..f8f65c0 --- /dev/null +++ b/plugins/doc_fragments/feature_template_vpn_vsmart_interface.py @@ -0,0 +1,299 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r""" +options: + vpn_vsmart_interface: + description: vSmart VPN Interface Feature Template configuration + type: dict + suboptions: + if_name: + description: + - The name of the interface. + required: false + default: null + type: str + interface_description: + description: + - A description for the interface. + required: false + default: null + type: str + ipv4_address: + description: + - The primary IPv4 address assigned to the interface. + required: false + default: null + type: str + dhcp_ipv4_client: + description: + - Whether DHCP client is enabled on the interface for IPv4 addressing. + True if enabled, False otherwise. + required: false + default: null + type: bool + dhcp_distance: + description: + - Administrative distance for DHCP routes on the interface. + required: false + default: null + type: int + ipv6_address: + description: + - The primary IPv6 address assigned to the interface. + required: false + default: null + type: str + dhcp_ipv6_client: + description: + - Whether DHCP client is enabled on the interface for IPv6 addressing. + True if enabled, False otherwise. + required: false + default: null + type: bool + dhcp_ipv6_distance: + description: + - Administrative distance for DHCP routes on the interface. + required: false + default: null + type: int + dhcp_rapid_commit: + description: + - Enable DHCPv6 rapid commit + required: false + default: null + type: bool + group: + description: + - Identifies the group or groups the interface belongs to. + required: false + default: null + type: list + elements: int + value: + description: + - The value field often corresponds to a specific attribute or setting, + such as color in this context. + required: false + default: null + type: str + choices: + - default + - mpls + - metro-ethernet + - biz-internet + - public-internet + - lte + - 3g + - red + - green + - blue + - gold + - silver + - bronze + - custom1 + - custom2 + - custom3 + - private1 + - private2 + - private3 + - private4 + - private5 + - private6 + carrier: + description: + - Specifies the carrier information for the tunnel interface. + required: false + default: null + type: str + choices: + - default + - carrier1 + - carrier2 + - carrier3 + - carrier4 + - carrier5 + - carrier6 + - carrier7 + - carrier8 + nat_refresh_interval: + description: + - Interval in seconds to refresh NAT (Network Address Translation) + mappings. + required: false + default: null + type: int + hello_interval: + description: + - Time interval in seconds between successive hello packets sent over + the tunnel interface. + required: false + default: null + type: int + hello_tolerance: + description: + - Time in seconds to wait before declaring a neighbor down due to + missing hello packets. + required: false + default: null + type: int + all: + description: + - Permits or denies all services through the tunnel interface. + required: false + default: null + type: bool + dhcp: + description: + - Enables or disables Dynamic Host Configuration Protocol (DHCP) on + the tunnel interface. + required: false + default: null + type: bool + dns: + description: + - Allows or disallows Domain Name System (DNS) queries through the + tunnel interface. + required: false + default: null + type: bool + icmp: + description: + - Enables or disables Internet Control Message Protocol (ICMP) for + ping and traceroute through the tunnel interface. + required: false + default: null + type: bool + sshd: + description: + - Allows or disallows Secure Shell (SSH) daemon access through the + tunnel interface. + required: false + default: null + type: bool + netconf: + description: + - Enables or disables NETCONF protocol support on the tunnel interface. + required: false + default: null + type: bool + ntp: + description: + - Allows or disallows Network Time Protocol (NTP) synchronization + through the tunnel interface. + required: false + default: null + type: bool + stun: + description: + - Enables or disables Session Traversal Utilities for NAT (STUN) on + the tunnel interface. + required: false + default: null + type: bool + flow_control: + description: + - Enable flow control. + required: false + default: null + type: str + choices: + - ingress + - egress + - autoneg + - both + - none + clear_dont_fragment: + description: + - Enables Clear don't fragment bit + required: false + default: false + type: bool + autonegotiate: + description: + - Link autonegotiation + required: false + default: true + type: bool + pmtu: + description: + - Enables Path MTU Discovery + required: false + default: false + type: bool + mtu: + description: + - Interface MTU <576..2000> + required: false + default: null + type: int + tcp_mss_adjust: + description: + - TCP MSS on SYN packets, in bytes + required: false + default: null + type: int + mac_address: + description: + - Specifies the MAC address for the interface. + required: false + default: null + type: str + speed: + description: + - Defines the speed of the interface, such as 10Mbps, 100Mbps, or + 1Gbps. + required: false + default: null + type: str + choices: + - '10' + - '100' + - '1000' + duplex: + description: + - Sets the duplex mode for the interface, such as full or half duplex. + required: false + default: null + type: str + choices: + - full + - half + shutdown: + description: + - Enables or disables (shuts down) the interface. + required: false + default: false + type: bool + ip: + description: + - A list of IP configurations for Address Resolution Protocol (ARP) + settings. + required: false + default: null + type: list + elements: dict + suboptions: + addr: + description: + - IPv4 address for the interface. + required: true + default: null + type: str + mac: + description: + - MAC address associated with the IPv4 address. + required: true + default: null + type: str + """ diff --git a/plugins/module_utils/feature_templates/aaa.py b/plugins/module_utils/feature_templates/aaa.py new file mode 100644 index 0000000..36b7b39 --- /dev/null +++ b/plugins/module_utils/feature_templates/aaa.py @@ -0,0 +1,144 @@ +aaa_definition = { + "aaa": { + "default": None, + "options": { + "accounting": {"default": False, "required": False, "type": "bool"}, + "admin_auth_order": {"default": False, "required": False, "type": "bool"}, + "audit_disable": {"default": False, "required": False, "type": "bool"}, + "auth_fallback": {"default": False, "required": False, "type": "bool"}, + "auth_order": { + "default": ["local", "radius", "tacacs"], + "elements": "str", + "required": False, + "type": "list", + }, + "cisco_tac_ro_user": {"default": True, "required": False, "type": "bool"}, + "cisco_tac_rw_user": {"default": True, "required": False, "type": "bool"}, + "netconf_disable": {"default": False, "required": False, "type": "bool"}, + "radius_retransmit": {"default": None, "required": False, "type": "int"}, + "radius_server": { + "default": None, + "elements": "dict", + "options": { + "acct_port": {"default": None, "required": False, "type": "int"}, + "address": {"default": None, "required": True, "type": "str"}, + "auth_port": {"default": None, "required": False, "type": "int"}, + "key": {"default": None, "required": False, "type": "str"}, + "priority": {"default": None, "required": False, "type": "int"}, + "secret_key": {"default": None, "required": False, "type": "str"}, + "source_interface": {"default": None, "required": False, "type": "str"}, + "tag": {"default": None, "required": False, "type": "str"}, + "vpn": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "radius_server_list": {"default": None, "elements": "str", "required": False, "type": "list"}, + "radius_timeout": {"default": None, "required": False, "type": "int"}, + "tacacs_authentication": {"default": "pap", "required": False, "type": "str"}, + "tacacs_server": { + "default": None, + "elements": "dict", + "options": { + "address": {"default": None, "required": True, "type": "str"}, + "auth_port": {"default": None, "required": False, "type": "int"}, + "key": {"default": None, "required": False, "type": "str"}, + "priority": {"default": None, "required": False, "type": "int"}, + "secret_key": {"default": None, "required": False, "type": "str"}, + "source_interface": {"default": None, "required": False, "type": "str"}, + "vpn": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "tacacs_timeout": {"default": None, "required": False, "type": "int"}, + "task": { + "default": None, + "elements": "dict", + "options": { + "config_accept_action": { + "default": None, + "elements": "dict", + "options": {"command": {"default": None, "required": True, "type": "str"}}, + "required": False, + "type": "list", + }, + "config_default_action": {"default": None, "required": True, "type": "str"}, + "config_deny_action": { + "default": None, + "elements": "dict", + "options": {"command": {"default": None, "required": True, "type": "str"}}, + "required": False, + "type": "list", + }, + "name": {"default": None, "required": True, "type": "str"}, + "oper_exec_accept_action": { + "default": None, + "elements": "dict", + "options": {"command": {"default": None, "required": True, "type": "str"}}, + "required": False, + "type": "list", + }, + "oper_exec_default_action": {"default": None, "required": True, "type": "str"}, + "oper_exec_deny_action": { + "default": None, + "elements": "dict", + "options": {"command": {"default": None, "required": True, "type": "str"}}, + "required": False, + "type": "list", + }, + "password": {"default": None, "required": False, "type": "str"}, + "privilege": {"default": "15", "required": False, "type": "str"}, + "secret": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "user": { + "default": None, + "elements": "dict", + "options": { + "description": {"default": None, "required": False, "type": "str"}, + "group": {"default": None, "elements": "str", "required": False, "type": "list"}, + "name": {"default": None, "required": True, "type": "str"}, + "password": {"default": None, "required": False, "type": "str"}, + "pubkey_chain": { + "default": None, + "elements": "dict", + "options": { + "key_string": {"default": None, "required": True, "type": "str"}, + "key_type": {"default": "ssh-rsa", "required": False, "type": "str"}, + "usertag": {"default": None, "required": True, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "secret": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "usergroup": { + "default": None, + "elements": "dict", + "options": { + "name": {"default": None, "required": True, "type": "str"}, + "task": { + "default": None, + "elements": "dict", + "options": { + "mode": {"default": None, "required": True, "type": "str"}, + "permission": {"default": "pap", "elements": "str", "required": False, "type": "list"}, + }, + "required": False, + "type": "list", + }, + }, + "required": False, + "type": "list", + }, + }, + "required": False, + "type": "dict", + } +} diff --git a/plugins/module_utils/feature_templates/cisco_aaa.py b/plugins/module_utils/feature_templates/cisco_aaa.py new file mode 100644 index 0000000..1d622d8 --- /dev/null +++ b/plugins/module_utils/feature_templates/cisco_aaa.py @@ -0,0 +1,140 @@ +cisco_aaa_definition = { + "cisco_aaa": { + "default": None, + "options": { + "accounting_group": {"default": False, "required": False, "type": "bool"}, + "accounting_rules": { + "default": None, + "elements": "dict", + "options": { + "group": {"default": None, "required": True, "type": "str"}, + "level": {"default": None, "required": False, "type": "str"}, + "method": {"default": None, "required": True, "type": "str"}, + "rule_id": {"default": None, "required": True, "type": "str"}, + "start_stop": {"default": True, "required": False, "type": "bool"}, + }, + "required": False, + "type": "list", + }, + "authentication_group": {"default": False, "required": False, "type": "bool"}, + "authentication_type": {"default": "any", "required": False, "type": "str"}, + "authorization_config_commands": {"default": None, "required": False, "type": "bool"}, + "authorization_console": {"default": None, "required": False, "type": "bool"}, + "authorization_rules": { + "default": None, + "elements": "dict", + "options": { + "authenticated": {"default": False, "required": False, "type": "bool"}, + "group": {"default": None, "required": True, "type": "str"}, + "level": {"default": None, "required": False, "type": "str"}, + "method": {"default": None, "required": True, "type": "str"}, + "rule_id": {"default": None, "required": True, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "cts_authorization_list": {"default": None, "required": False, "type": "str"}, + "domain_stripping": {"default": None, "required": False, "type": "str"}, + "port": {"default": None, "required": False, "type": "int"}, + "radius": { + "default": None, + "elements": "dict", + "options": { + "group_name": {"default": None, "required": True, "type": "str"}, + "server": { + "default": [], + "elements": "dict", + "options": { + "acct_port": {"default": None, "required": False, "type": "int"}, + "address": {"default": None, "required": True, "type": "str"}, + "auth_port": {"default": None, "required": False, "type": "int"}, + "key": {"default": None, "required": True, "type": "str"}, + "key_enum": {"default": None, "required": False, "type": "str"}, + "key_type": {"default": None, "required": False, "type": "str"}, + "retransmit": {"default": None, "required": False, "type": "int"}, + "secret_key": {"default": None, "required": False, "type": "str"}, + "timeout": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "source_interface": {"default": None, "required": True, "type": "str"}, + "vpn": {"default": None, "required": True, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "radius_client": { + "default": None, + "elements": "dict", + "options": { + "ip": {"default": None, "required": True, "type": "str"}, + "vpn": { + "default": None, + "elements": "dict", + "options": { + "name": {"default": None, "required": True, "type": "str"}, + "server_key": {"default": None, "required": False, "type": "str"}, + }, + "required": True, + "type": "list", + }, + }, + "required": False, + "type": "list", + }, + "radius_trustsec_group": {"default": None, "required": False, "type": "str"}, + "server_auth_order": {"default": "local", "required": False, "type": "str"}, + "server_key_password": {"default": None, "required": False, "type": "str"}, + "tacacs": { + "default": None, + "elements": "dict", + "options": { + "group_name": {"default": None, "required": True, "type": "str"}, + "server": { + "default": [], + "elements": "dict", + "options": { + "address": {"default": None, "required": True, "type": "str"}, + "key": {"default": None, "required": True, "type": "str"}, + "key_enum": {"default": None, "required": False, "type": "str"}, + "port": {"default": None, "required": False, "type": "int"}, + "secret_key": {"default": None, "required": False, "type": "str"}, + "timeout": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "source_interface": {"default": None, "required": False, "type": "str"}, + "vpn": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "user": { + "default": None, + "elements": "dict", + "options": { + "name": {"default": None, "required": True, "type": "str"}, + "password": {"default": None, "required": False, "type": "str"}, + "privilege": {"default": "15", "required": False, "type": "str"}, + "pubkey_chain": { + "default": None, + "elements": "dict", + "options": { + "key_string": {"default": None, "required": True, "type": "str"}, + "key_type": {"default": "ssh-rsa", "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "secret": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + }, + "required": False, + "type": "dict", + } +} diff --git a/plugins/module_utils/feature_templates/cisco_banner.py b/plugins/module_utils/feature_templates/cisco_banner.py new file mode 100644 index 0000000..94dc562 --- /dev/null +++ b/plugins/module_utils/feature_templates/cisco_banner.py @@ -0,0 +1,11 @@ +cisco_banner_definition = { + "cisco_banner": { + "default": None, + "options": { + "login_banner": {"default": None, "required": False, "type": "str"}, + "motd_banner": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "dict", + } +} diff --git a/plugins/module_utils/feature_templates/cisco_bfd.py b/plugins/module_utils/feature_templates/cisco_bfd.py new file mode 100644 index 0000000..e327be7 --- /dev/null +++ b/plugins/module_utils/feature_templates/cisco_bfd.py @@ -0,0 +1,25 @@ +cisco_bfd_definition = { + "cisco_bfd": { + "default": None, + "options": { + "color": { + "default": None, + "elements": "dict", + "options": { + "color": {"default": None, "required": True, "type": "str"}, + "dscp": {"default": None, "required": False, "type": "int"}, + "hello_interval": {"default": None, "required": False, "type": "int"}, + "multiplier": {"default": None, "required": False, "type": "int"}, + "pmtu_discovery": {"default": True, "required": False, "type": "bool"}, + }, + "required": False, + "type": "list", + }, + "default_dscp": {"default": None, "required": False, "type": "int"}, + "multiplier": {"default": None, "required": False, "type": "int"}, + "poll_interval": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "dict", + } +} diff --git a/plugins/module_utils/feature_templates/cisco_logging.py b/plugins/module_utils/feature_templates/cisco_logging.py new file mode 100644 index 0000000..4c1bb30 --- /dev/null +++ b/plugins/module_utils/feature_templates/cisco_logging.py @@ -0,0 +1,54 @@ +cisco_logging_definition = { + "cisco_logging": { + "default": None, + "options": { + "enable": {"default": None, "required": False, "type": "bool"}, + "ipv6_server": { + "default": None, + "elements": "dict", + "options": { + "custom_profile": {"default": False, "required": False, "type": "bool"}, + "enable_tls": {"default": False, "required": False, "type": "bool"}, + "name": {"default": None, "required": True, "type": "str"}, + "priority": {"default": "information", "required": False, "type": "str"}, + "profile": {"default": None, "required": False, "type": "str"}, + "source_interface": {"default": None, "required": False, "type": "str"}, + "vpn": {"default": None, "required": True, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "rotate": {"default": None, "required": False, "type": "int"}, + "server": { + "default": None, + "elements": "dict", + "options": { + "custom_profile": {"default": False, "required": False, "type": "bool"}, + "enable_tls": {"default": False, "required": False, "type": "bool"}, + "name": {"default": None, "required": True, "type": "str"}, + "priority": {"default": "information", "required": False, "type": "str"}, + "profile": {"default": None, "required": False, "type": "str"}, + "source_interface": {"default": None, "required": False, "type": "str"}, + "vpn": {"default": None, "required": True, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "size": {"default": None, "required": False, "type": "int"}, + "tls_profile": { + "default": None, + "elements": "dict", + "options": { + "auth_type": {"default": None, "required": True, "type": "str"}, + "ciphersuite_list": {"default": None, "elements": "str", "required": False, "type": "list"}, + "profile": {"default": None, "required": True, "type": "str"}, + "version": {"default": "TLSv1.1", "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + }, + "required": False, + "type": "dict", + } +} diff --git a/plugins/module_utils/feature_templates/cisco_ntp.py b/plugins/module_utils/feature_templates/cisco_ntp.py new file mode 100644 index 0000000..6ac3117 --- /dev/null +++ b/plugins/module_utils/feature_templates/cisco_ntp.py @@ -0,0 +1,37 @@ +cisco_ntp_definition = { + "cisco_ntp": { + "default": None, + "options": { + "authentication": { + "default": None, + "elements": "dict", + "options": { + "md5": {"default": None, "required": True, "type": "str"}, + "number": {"default": None, "required": True, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "enable": {"default": None, "required": False, "type": "bool"}, + "server": { + "default": [], + "elements": "dict", + "options": { + "key": {"default": None, "required": False, "type": "int"}, + "name": {"default": None, "required": True, "type": "str"}, + "prefer": {"default": None, "required": False, "type": "bool"}, + "source_interface": {"default": None, "required": False, "type": "str"}, + "version": {"default": None, "required": False, "type": "int"}, + "vpn": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "source": {"default": None, "required": False, "type": "str"}, + "stratum": {"default": None, "required": False, "type": "int"}, + "trusted": {"default": None, "elements": "int", "required": False, "type": "list"}, + }, + "required": False, + "type": "dict", + } +} diff --git a/plugins/module_utils/feature_templates/cisco_omp.py b/plugins/module_utils/feature_templates/cisco_omp.py new file mode 100644 index 0000000..6eb5021 --- /dev/null +++ b/plugins/module_utils/feature_templates/cisco_omp.py @@ -0,0 +1,41 @@ +cisco_omp_definition = { + "cisco_omp": { + "default": None, + "options": { + "advertise": { + "default": None, + "elements": "dict", + "options": { + "protocol": {"default": None, "required": True, "type": "str"}, + "route": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "advertisement_interval": {"default": None, "required": False, "type": "int"}, + "auto_translate": {"default": False, "required": False, "type": "bool"}, + "ecmp_limit": {"default": None, "required": False, "type": "int"}, + "eor_timer": {"default": None, "required": False, "type": "int"}, + "graceful_restart": {"default": True, "required": False, "type": "bool"}, + "graceful_restart_timer": {"default": None, "required": False, "type": "int"}, + "holdtime": {"default": None, "required": False, "type": "int"}, + "ignore_region_path_length": {"default": False, "required": False, "type": "bool"}, + "ipv6_advertise": { + "default": None, + "elements": "dict", + "options": {"protocol": {"default": None, "required": True, "type": "str"}}, + "required": False, + "type": "list", + }, + "omp_admin_distance_ipv4": {"default": None, "required": False, "type": "int"}, + "omp_admin_distance_ipv6": {"default": None, "required": False, "type": "int"}, + "overlay_as": {"default": None, "required": False, "type": "int"}, + "send_path_limit": {"default": None, "required": False, "type": "int"}, + "shutdown": {"default": None, "required": False, "type": "bool"}, + "site_types": {"default": None, "elements": "str", "required": False, "type": "list"}, + "transport_gateway": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "dict", + } +} diff --git a/plugins/module_utils/feature_templates/cisco_ospf.py b/plugins/module_utils/feature_templates/cisco_ospf.py new file mode 100644 index 0000000..925f44e --- /dev/null +++ b/plugins/module_utils/feature_templates/cisco_ospf.py @@ -0,0 +1,94 @@ +cisco_ospf_definition = { + "cisco_ospf": { + "default": None, + "options": { + "always": {"default": None, "required": False, "type": "bool"}, + "area": { + "default": None, + "elements": "dict", + "options": { + "a_num": {"default": None, "required": True, "type": "int"}, + "interface": { + "default": None, + "elements": "dict", + "options": { + "cost": {"default": None, "required": False, "type": "int"}, + "dead_interval": {"default": None, "required": False, "type": "int"}, + "hello_interval": {"default": None, "required": False, "type": "int"}, + "md5": {"default": None, "required": False, "type": "str"}, + "message_digest_key": {"default": None, "required": False, "type": "int"}, + "name": {"default": None, "required": True, "type": "str"}, + "network": {"default": "broadcast", "required": False, "type": "str"}, + "passive_interface": {"default": False, "required": False, "type": "bool"}, + "priority": {"default": None, "required": False, "type": "int"}, + "retransmit_interval": {"default": None, "required": False, "type": "int"}, + "type": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "nssa": {"default": None, "required": False, "type": "bool"}, + "range": { + "default": None, + "elements": "dict", + "options": { + "address": {"default": None, "required": True, "type": "str"}, + "cost": {"default": None, "required": False, "type": "int"}, + "no_advertise": {"default": False, "required": False, "type": "bool"}, + }, + "required": False, + "type": "list", + }, + "stub": {"default": None, "required": False, "type": "bool"}, + }, + "required": False, + "type": "list", + }, + "delay": {"default": None, "required": False, "type": "int"}, + "external": {"default": None, "required": False, "type": "int"}, + "initial_hold": {"default": None, "required": False, "type": "int"}, + "inter_area": {"default": None, "required": False, "type": "int"}, + "intra_area": {"default": None, "required": False, "type": "int"}, + "max_hold": {"default": None, "required": False, "type": "int"}, + "metric": {"default": None, "required": False, "type": "int"}, + "metric_type": {"default": None, "required": False, "type": "str"}, + "originate": {"default": None, "required": False, "type": "bool"}, + "redistribute": { + "default": None, + "elements": "dict", + "options": { + "dia": {"default": True, "required": False, "type": "bool"}, + "protocol": {"default": None, "required": True, "type": "str"}, + "route_policy": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "reference_bandwidth": {"default": None, "required": False, "type": "int"}, + "rfc1583": {"default": True, "required": False, "type": "bool"}, + "route_policy": { + "default": None, + "elements": "dict", + "options": { + "direction": {"default": None, "required": True, "type": "str"}, + "pol_name": {"default": None, "required": True, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "router_id": {"default": None, "required": False, "type": "str"}, + "router_lsa": { + "default": None, + "elements": "dict", + "options": { + "ad_type": {"default": None, "required": True, "type": "str"}, + "time": {"default": None, "required": True, "type": "int"}, + }, + "required": False, + "type": "list", + }, + }, + "required": False, + "type": "dict", + } +} diff --git a/plugins/module_utils/feature_templates/cisco_secure_internet_gateway.py b/plugins/module_utils/feature_templates/cisco_secure_internet_gateway.py new file mode 100644 index 0000000..da2a98d --- /dev/null +++ b/plugins/module_utils/feature_templates/cisco_secure_internet_gateway.py @@ -0,0 +1,107 @@ +cisco_secure_internet_gateway_definition = { + "cisco_secure_internet_gateway": { + "default": None, + "options": { + "child_org_id": {"default": "", "required": False, "type": "str"}, + "interface": { + "default": None, + "elements": "dict", + "options": { + "address": {"default": None, "required": False, "type": "str"}, + "application": {"default": "sig", "required": False, "type": "str"}, + "auto": {"default": None, "required": True, "type": "bool"}, + "description": {"default": None, "required": False, "type": "str"}, + "dpd_interval": {"default": None, "required": False, "type": "int"}, + "dpd_retries": {"default": None, "required": False, "type": "int"}, + "if_name": {"default": None, "required": True, "type": "str"}, + "ike_ciphersuite": {"default": "aes256-cbc-sha1", "required": False, "type": "str"}, + "ike_group": {"default": "14", "required": False, "type": "str"}, + "ike_local_id": {"default": None, "required": False, "type": "str"}, + "ike_rekey_interval": {"default": None, "required": False, "type": "int"}, + "ike_remote_id": {"default": None, "required": False, "type": "str"}, + "ike_version": {"default": None, "required": False, "type": "int"}, + "ipsec_ciphersuite": {"default": "aes256-gcm", "required": False, "type": "str"}, + "ipsec_rekey_interval": {"default": None, "required": False, "type": "int"}, + "ipsec_replay_window": {"default": None, "required": False, "type": "int"}, + "mtu": {"default": None, "required": False, "type": "int"}, + "perfect_forward_secrecy": {"default": "none", "required": False, "type": "str"}, + "pre_shared_key_dynamic": {"default": None, "required": False, "type": "bool"}, + "pre_shared_secret": {"default": None, "required": False, "type": "str"}, + "shutdown": {"default": None, "required": True, "type": "bool"}, + "tcp_mss_adjust": {"default": None, "required": False, "type": "int"}, + "track_enable": {"default": None, "required": False, "type": "bool"}, + "tracker": {"default": None, "required": False, "type": "bool"}, + "tunnel_dc_preference": {"default": "primary-dc", "required": False, "type": "str"}, + "tunnel_destination": {"default": None, "required": True, "type": "str"}, + "tunnel_public_ip": {"default": None, "required": False, "type": "str"}, + "tunnel_route_via": {"default": None, "required": False, "type": "str"}, + "tunnel_set": {"default": "secure-internet-gateway-umbrella", "required": False, "type": "str"}, + "tunnel_source": {"default": None, "required": False, "type": "str"}, + "tunnel_source_interface": {"default": None, "required": False, "type": "str"}, + "unnumbered": {"default": None, "required": False, "type": "bool"}, + }, + "required": True, + "type": "list", + }, + "service": { + "default": None, + "elements": "dict", + "options": { + "auth_required": {"default": None, "required": False, "type": "bool"}, + "block_internet_until_accepted": {"default": None, "required": False, "type": "bool"}, + "caution_enabled": {"default": None, "required": False, "type": "bool"}, + "data_center_primary": {"default": "Auto", "required": False, "type": "str"}, + "data_center_secondary": {"default": "Auto", "required": False, "type": "str"}, + "display_time_unit": {"default": "MINUTE", "required": False, "type": "str"}, + "enabled": {"default": None, "required": False, "type": "bool"}, + "force_ssl_inspection": {"default": None, "required": False, "type": "bool"}, + "idle_time": {"default": None, "required": False, "type": "int"}, + "interface_pair": { + "default": None, + "elements": "dict", + "options": { + "active_interface": {"default": None, "required": True, "type": "str"}, + "active_interface_weight": {"default": None, "required": False, "type": "int"}, + "backup_interface": {"default": None, "required": False, "type": "str"}, + "backup_interface_weight": {"default": None, "required": False, "type": "int"}, + }, + "required": True, + "type": "list", + }, + "ip": {"default": None, "required": False, "type": "bool"}, + "ip_enforced_for_known_browsers": {"default": None, "required": False, "type": "bool"}, + "ips_control": {"default": None, "required": False, "type": "bool"}, + "location_name": {"default": "Auto", "required": False, "type": "str"}, + "ofw_enabled": {"default": None, "required": False, "type": "bool"}, + "primary_data_center": {"default": "Auto", "required": False, "type": "str"}, + "refresh_time": {"default": None, "required": False, "type": "int"}, + "refresh_time_unit": {"default": "MINUTE", "required": False, "type": "str"}, + "secondary_data_center": {"default": "Auto", "required": False, "type": "str"}, + "svc_type": {"default": "sig", "required": False, "type": "str"}, + "timeout": {"default": None, "required": False, "type": "int"}, + "xff_forward_enabled": {"default": None, "required": False, "type": "bool"}, + }, + "required": True, + "type": "list", + }, + "tracker": { + "default": None, + "elements": "dict", + "options": { + "endpoint_api_url": {"default": None, "required": True, "type": "str"}, + "interval": {"default": None, "required": False, "type": "int"}, + "multiplier": {"default": None, "required": False, "type": "int"}, + "name": {"default": None, "required": True, "type": "str"}, + "threshold": {"default": None, "required": False, "type": "int"}, + "tracker_type": {"default": None, "required": True, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "tracker_src_ip": {"default": None, "required": False, "type": "str"}, + "vpn_id": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "dict", + } +} diff --git a/plugins/module_utils/feature_templates/cisco_snmp.py b/plugins/module_utils/feature_templates/cisco_snmp.py new file mode 100644 index 0000000..1018a10 --- /dev/null +++ b/plugins/module_utils/feature_templates/cisco_snmp.py @@ -0,0 +1,81 @@ +cisco_snmp_definition = { + "cisco_snmp": { + "default": None, + "options": { + "community": { + "default": None, + "elements": "dict", + "options": { + "authorization": {"default": None, "required": True, "type": "str"}, + "name": {"default": None, "required": True, "type": "str"}, + "view": {"default": None, "required": True, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "contact": {"default": None, "required": False, "type": "str"}, + "group": { + "default": None, + "elements": "dict", + "options": { + "name": {"default": None, "required": True, "type": "str"}, + "security_level": {"default": None, "required": True, "type": "str"}, + "view": {"default": None, "required": True, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "location": {"default": None, "required": False, "type": "str"}, + "shutdown": {"default": True, "required": False, "type": "bool"}, + "target": { + "default": None, + "elements": "dict", + "options": { + "community_name": {"default": None, "required": False, "type": "str"}, + "ip": {"default": None, "required": True, "type": "str"}, + "port": {"default": None, "required": True, "type": "int"}, + "source_interface": {"default": None, "required": False, "type": "str"}, + "user": {"default": None, "required": False, "type": "str"}, + "vpn_id": {"default": None, "required": True, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "user": { + "default": None, + "elements": "dict", + "options": { + "auth": {"default": None, "required": False, "type": "str"}, + "auth_password": {"default": None, "required": False, "type": "str"}, + "group": {"default": None, "required": True, "type": "str"}, + "name": {"default": None, "required": True, "type": "str"}, + "priv": {"default": None, "required": False, "type": "str"}, + "priv_password": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "view": { + "default": None, + "elements": "dict", + "options": { + "name": {"default": None, "required": True, "type": "str"}, + "oid": { + "default": None, + "elements": "dict", + "options": { + "exclude": {"default": None, "required": False, "type": "bool"}, + "id": {"default": None, "required": True, "type": "str"}, + }, + "required": False, + "type": "list", + }, + }, + "required": False, + "type": "list", + }, + }, + "required": False, + "type": "dict", + } +} diff --git a/plugins/module_utils/feature_templates/cisco_system.py b/plugins/module_utils/feature_templates/cisco_system.py new file mode 100644 index 0000000..078caa7 --- /dev/null +++ b/plugins/module_utils/feature_templates/cisco_system.py @@ -0,0 +1,129 @@ +cisco_system_definition = { + "cisco_system": { + "default": None, + "options": { + "admin_tech_on_failure": {"default": None, "required": False, "type": "bool"}, + "affinity_group_number": {"default": None, "required": False, "type": "int"}, + "affinity_per_vrf": { + "default": None, + "elements": "dict", + "options": { + "affinity_group_number": {"default": None, "required": False, "type": "int"}, + "vrf_range": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "console_baud_rate": {"default": None, "required": False, "type": "str"}, + "control_session_pps": {"default": None, "required": False, "type": "int"}, + "controller_group_list": {"default": None, "elements": "int", "required": False, "type": "list"}, + "description": {"default": None, "required": False, "type": "str"}, + "device_groups": {"default": None, "elements": "str", "required": False, "type": "list"}, + "enable_fencing": {"default": None, "required": False, "type": "bool"}, + "enable_management_region": {"default": None, "required": False, "type": "bool"}, + "enable_mrf_migration": {"default": None, "required": False, "type": "str"}, + "enable_sms": {"default": False, "required": False, "type": "bool"}, + "enable_tunnel": {"default": None, "required": False, "type": "bool"}, + "epfr": {"default": None, "required": False, "type": "str"}, + "hostname": { + "default": None, + "options": {"name": {"default": "system_host_name", "required": True, "type": "str"}}, + "required": False, + "type": "raw", + }, + "idle_timeout": {"default": None, "required": False, "type": "int"}, + "latitude": {"default": None, "required": False, "type": "str"}, + "location": {"default": None, "required": False, "type": "str"}, + "longitude": {"default": None, "required": False, "type": "str"}, + "management_gateway": {"default": None, "required": False, "type": "bool"}, + "max_omp_sessions": {"default": None, "required": False, "type": "int"}, + "migration_bgp_community": {"default": None, "required": False, "type": "int"}, + "mobile_number": { + "default": None, + "elements": "dict", + "options": {"number": {"default": None, "required": True, "type": "str"}}, + "required": False, + "type": "list", + }, + "multi_tenant": {"default": None, "required": False, "type": "bool"}, + "object_track": { + "default": None, + "elements": "dict", + "options": { + "boolean": {"default": None, "required": True, "type": "str"}, + "interface": {"default": None, "required": True, "type": "str"}, + "ip": {"default": None, "required": True, "type": "str"}, + "mask": {"default": "0.0.0.0", "required": False, "type": "str"}, + "object": { + "default": None, + "elements": "dict", + "options": {"number": {"default": None, "required": True, "type": "int"}}, + "required": True, + "type": "list", + }, + "object_number": {"default": None, "required": True, "type": "int"}, + "sig": {"default": None, "required": True, "type": "str"}, + "vpn": {"default": None, "required": True, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "on_demand_idle_timeout_min": {"default": None, "required": False, "type": "int"}, + "overlay_id": {"default": None, "required": False, "type": "int"}, + "port_hop": {"default": None, "required": False, "type": "bool"}, + "port_offset": {"default": None, "required": False, "type": "int"}, + "preference": {"default": None, "elements": "int", "required": False, "type": "list"}, + "preference_auto": {"default": None, "required": False, "type": "bool"}, + "range": {"default": None, "required": False, "type": "int"}, + "region_id": {"default": None, "required": False, "type": "int"}, + "role": {"default": None, "required": False, "type": "str"}, + "secondary_region": {"default": None, "required": False, "type": "int"}, + "site_id": {"default": "system_site_id", "required": False, "type": "int"}, + "site_type": {"default": None, "elements": "str", "required": False, "type": "list"}, + "system_ip": { + "default": None, + "options": {"name": {"default": "system_system_ip", "required": True, "type": "str"}}, + "required": False, + "type": "raw", + }, + "timezone": {"default": None, "required": False, "type": "str"}, + "track_default_gateway": {"default": None, "required": False, "type": "bool"}, + "track_interface_tag": {"default": None, "required": False, "type": "int"}, + "track_transport": {"default": None, "required": False, "type": "bool"}, + "tracker": { + "default": None, + "elements": "dict", + "options": { + "boolean": {"default": "or", "required": False, "type": "str"}, + "elements": {"default": None, "elements": "str", "required": False, "type": "list"}, + "endpoint_api_url": {"default": None, "required": False, "type": "str"}, + "endpoint_dns_name": {"default": None, "required": False, "type": "str"}, + "endpoint_ip": {"default": None, "required": False, "type": "str"}, + "endpoint_ip_transport_port": {"default": None, "required": False, "type": "str"}, + "interval": {"default": None, "required": False, "type": "int"}, + "multiplier": {"default": None, "required": False, "type": "int"}, + "name": {"default": None, "required": True, "type": "str"}, + "port": {"default": None, "required": False, "type": "int"}, + "protocol": {"default": None, "required": False, "type": "str"}, + "threshold": {"default": None, "required": False, "type": "int"}, + "type": {"default": "interface", "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "transport_gateway": {"default": None, "required": False, "type": "bool"}, + "vrf": { + "default": None, + "elements": "dict", + "options": { + "gateway_preference": {"default": None, "elements": "int", "required": False, "type": "list"}, + "vrf_id": {"default": None, "required": True, "type": "int"}, + }, + "required": False, + "type": "list", + }, + }, + "required": False, + "type": "dict", + } +} diff --git a/plugins/module_utils/feature_templates/cisco_vpn.py b/plugins/module_utils/feature_templates/cisco_vpn.py new file mode 100644 index 0000000..74a7940 --- /dev/null +++ b/plugins/module_utils/feature_templates/cisco_vpn.py @@ -0,0 +1,343 @@ +cisco_vpn_definition = { + "cisco_vpn": { + "default": None, + "options": { + "advertise": { + "default": None, + "elements": "dict", + "options": { + "prefix_list": { + "default": None, + "elements": "dict", + "options": { + "aggregate_only": {"default": None, "required": False, "type": "bool"}, + "prefix_entry": {"default": None, "required": True, "type": "str"}, + "region": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "protocol": {"default": None, "required": True, "type": "str"}, + "protocol_sub_type": {"default": None, "elements": "str", "required": False, "type": "list"}, + "route_policy": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "dns": { + "default": None, + "elements": "dict", + "options": { + "dns_addr": {"default": None, "required": False, "type": "str"}, + "role": {"default": "primary", "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "dns_ipv6": { + "default": None, + "elements": "dict", + "options": { + "dns_addr": {"default": None, "required": False, "type": "str"}, + "role": {"default": "primary", "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "gre_route": { + "default": None, + "elements": "dict", + "options": { + "interface": {"default": None, "elements": "str", "required": False, "type": "list"}, + "prefix": {"default": None, "required": True, "type": "str"}, + "vpn": {"default": None, "required": True, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "host": { + "default": None, + "elements": "dict", + "options": { + "hostname": {"default": None, "required": True, "type": "str"}, + "ip": {"default": None, "elements": "str", "required": True, "type": "list"}, + }, + "required": False, + "type": "list", + }, + "ipsec_route": { + "default": None, + "elements": "dict", + "options": { + "interface": {"default": None, "elements": "str", "required": False, "type": "list"}, + "prefix": {"default": None, "required": True, "type": "str"}, + "vpn": {"default": None, "required": True, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "ipv6_advertise": { + "default": None, + "elements": "dict", + "options": { + "prefix_list": { + "default": None, + "elements": "dict", + "options": { + "aggregate_only": {"default": None, "required": False, "type": "bool"}, + "prefix_entry": {"default": None, "required": True, "type": "str"}, + "region": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "protocol": {"default": None, "required": True, "type": "str"}, + "protocol_sub_type": {"default": None, "elements": "str", "required": False, "type": "list"}, + "route_policy": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "layer4": {"default": None, "required": False, "type": "bool"}, + "natpool": { + "default": None, + "elements": "dict", + "options": { + "direction": {"default": None, "required": True, "type": "str"}, + "name": {"default": None, "required": True, "type": "int"}, + "overload": {"default": "true", "required": False, "type": "str"}, + "prefix_length": {"default": None, "required": False, "type": "int"}, + "range_end": {"default": None, "required": False, "type": "str"}, + "range_start": {"default": None, "required": False, "type": "str"}, + "tracker_id": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "omp_admin_distance_ipv4": {"default": None, "required": False, "type": "int"}, + "omp_admin_distance_ipv6": {"default": None, "required": False, "type": "int"}, + "org_name": {"default": None, "required": False, "type": "str"}, + "pool": { + "default": None, + "elements": "dict", + "options": { + "end_address": {"default": None, "required": True, "type": "str"}, + "leak_from_global": {"default": None, "required": True, "type": "bool"}, + "leak_from_global_protocol": {"default": None, "required": True, "type": "str"}, + "leak_to_global": {"default": None, "required": True, "type": "bool"}, + "name": {"default": None, "required": True, "type": "str"}, + "overload": {"default": None, "required": False, "type": "bool"}, + "start_address": {"default": None, "required": True, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "port_forward": { + "default": None, + "elements": "dict", + "options": { + "pool_name": {"default": None, "required": False, "type": "int"}, + "proto": {"default": None, "required": True, "type": "str"}, + "source_ip": {"default": None, "required": True, "type": "str"}, + "source_port": {"default": None, "required": True, "type": "int"}, + "translate_ip": {"default": None, "required": True, "type": "str"}, + "translate_port": {"default": None, "required": True, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "route_export": { + "default": None, + "elements": "dict", + "options": { + "protocol": {"default": None, "required": True, "type": "str"}, + "protocol_sub_type": {"default": None, "elements": "str", "required": True, "type": "list"}, + "redistribute": { + "default": None, + "elements": "dict", + "options": { + "protocol": {"default": None, "required": True, "type": "str"}, + "route_policy": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "route_policy": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "route_import": { + "default": None, + "elements": "dict", + "options": { + "protocol": {"default": None, "required": True, "type": "str"}, + "protocol_sub_type": {"default": None, "elements": "str", "required": True, "type": "list"}, + "redistribute": { + "default": None, + "elements": "dict", + "options": { + "protocol": {"default": None, "required": True, "type": "str"}, + "route_policy": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "route_policy": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "route_import_from": { + "default": None, + "elements": "dict", + "options": { + "protocol": {"default": None, "required": True, "type": "str"}, + "protocol_sub_type": {"default": None, "elements": "str", "required": True, "type": "list"}, + "redistribute": { + "default": None, + "elements": "dict", + "options": { + "protocol": {"default": None, "required": True, "type": "str"}, + "route_policy": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "route_policy": {"default": None, "required": False, "type": "str"}, + "source_vpn": {"default": None, "required": True, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "route_v4": { + "default": None, + "elements": "dict", + "options": { + "dhcp": {"default": None, "required": False, "type": "bool"}, + "distance": {"default": None, "required": False, "type": "int"}, + "next_hop": { + "default": None, + "elements": "dict", + "options": { + "address": {"default": None, "required": False, "type": "str"}, + "distance": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "next_hop_with_track": { + "default": None, + "elements": "dict", + "options": { + "address": {"default": None, "required": False, "type": "str"}, + "distance": {"default": None, "required": False, "type": "int"}, + "tracker": {"default": None, "required": True, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "null0": {"default": None, "required": False, "type": "bool"}, + "prefix": {"default": None, "required": False, "type": "str"}, + "route_interface": { + "default": None, + "options": { + "interface_name": {"default": None, "required": True, "type": "str"}, + "interface_next_hop": { + "default": None, + "elements": "dict", + "options": { + "address": {"default": None, "required": False, "type": "str"}, + "distance": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "list", + }, + }, + "required": False, + "type": "dict", + }, + "vpn": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "route_v6": { + "default": None, + "elements": "dict", + "options": { + "nat": {"default": None, "required": False, "type": "str"}, + "next_hop": { + "default": None, + "elements": "dict", + "options": { + "address": {"default": None, "required": True, "type": "str"}, + "distance": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "null0": {"default": None, "required": False, "type": "bool"}, + "prefix": {"default": None, "required": True, "type": "str"}, + "vpn": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "service": { + "default": None, + "elements": "dict", + "options": { + "address": {"default": None, "elements": "str", "required": False, "type": "list"}, + "interface": {"default": None, "required": False, "type": "str"}, + "svc_type": {"default": None, "required": True, "type": "str"}, + "track_enable": {"default": None, "required": False, "type": "bool"}, + }, + "required": False, + "type": "list", + }, + "service_route": { + "default": None, + "elements": "dict", + "options": { + "prefix": {"default": None, "required": True, "type": "str"}, + "service": {"default": "sig", "required": False, "type": "str"}, + "vpn": {"default": None, "required": True, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "static": { + "default": None, + "elements": "dict", + "options": { + "pool_name": {"default": None, "required": False, "type": "int"}, + "source_ip": {"default": None, "required": False, "type": "str"}, + "static_nat_direction": {"default": None, "required": True, "type": "str"}, + "tracker_id": {"default": None, "required": False, "type": "int"}, + "translate_ip": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "subnet_static": { + "default": None, + "elements": "dict", + "options": { + "prefix_length": {"default": None, "required": True, "type": "int"}, + "source_ip_subnet": {"default": None, "required": True, "type": "str"}, + "static_nat_direction": {"default": None, "required": True, "type": "str"}, + "tracker_id": {"default": None, "required": False, "type": "int"}, + "translate_ip_subnet": {"default": None, "required": True, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "tenant_vpn_id": {"default": None, "required": False, "type": "int"}, + "vpn_id": {"default": None, "required": False, "type": "int"}, + "vpn_name": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "dict", + } +} diff --git a/plugins/module_utils/feature_templates/cisco_vpn_interface.py b/plugins/module_utils/feature_templates/cisco_vpn_interface.py new file mode 100644 index 0000000..d056248 --- /dev/null +++ b/plugins/module_utils/feature_templates/cisco_vpn_interface.py @@ -0,0 +1,272 @@ +cisco_vpn_interface_definition = { + "cisco_vpn_interface": { + "default": None, + "options": { + "access_list_ipv4": { + "default": None, + "elements": "dict", + "options": { + "acl_name": {"default": None, "required": True, "type": "str"}, + "direction": {"default": None, "required": True, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "access_list_ipv6": { + "default": None, + "elements": "dict", + "options": { + "acl_name": {"default": None, "required": True, "type": "str"}, + "direction": {"default": None, "required": True, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "all": {"default": None, "required": False, "type": "bool"}, + "arp_timeout": {"default": None, "required": False, "type": "int"}, + "auto_bandwidth_detect": {"default": None, "required": False, "type": "bool"}, + "autonegotiate": {"default": None, "required": False, "type": "bool"}, + "bandwidth_down": {"default": None, "required": False, "type": "int"}, + "bandwidth_downstream": {"default": None, "required": False, "type": "int"}, + "bandwidth_up": {"default": None, "required": False, "type": "int"}, + "bandwidth_upstream": {"default": None, "required": False, "type": "int"}, + "bgp": {"default": None, "required": False, "type": "bool"}, + "bind": {"default": None, "required": False, "type": "str"}, + "block_non_source_ip": {"default": None, "required": False, "type": "bool"}, + "border": {"default": None, "required": False, "type": "bool"}, + "carrier": {"default": None, "required": False, "type": "str"}, + "clear_dont_fragment": {"default": None, "required": False, "type": "bool"}, + "control_connections": {"default": None, "required": False, "type": "bool"}, + "core_region": {"default": None, "required": False, "type": "str"}, + "dhcp": {"default": None, "required": False, "type": "bool"}, + "dhcp_distance": {"default": None, "required": False, "type": "int"}, + "dhcp_helper": {"default": None, "elements": "str", "required": False, "type": "list"}, + "dhcp_helper_v6": { + "default": None, + "elements": "dict", + "options": { + "address": {"default": None, "required": True, "type": "str"}, + "vpn": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "dhcp_ipv4_client": {"default": None, "required": False, "type": "bool"}, + "dhcp_ipv6_client": {"default": None, "required": False, "type": "bool"}, + "dmax": {"default": None, "required": False, "type": "int"}, + "dmin": {"default": None, "required": False, "type": "int"}, + "dns": {"default": None, "required": False, "type": "bool"}, + "dst_ip": {"default": None, "required": False, "type": "str"}, + "duplex": {"default": None, "required": False, "type": "str"}, + "enable": {"default": None, "required": False, "type": "bool"}, + "enable_core_region": {"default": None, "required": False, "type": "bool"}, + "enable_sgt_authorization_and_forwarding": {"default": None, "required": False, "type": "bool"}, + "enable_sgt_enforcement": {"default": None, "required": False, "type": "bool"}, + "enable_sgt_propagation": {"default": None, "required": False, "type": "bool"}, + "enforcement_sgt": {"default": None, "required": False, "type": "int"}, + "exclude_controller_group_list": {"default": None, "elements": "int", "required": False, "type": "list"}, + "group": {"default": None, "elements": "int", "required": False, "type": "list"}, + "hello_interval": {"default": None, "required": False, "type": "int"}, + "hello_tolerance": {"default": None, "required": False, "type": "int"}, + "https": {"default": None, "required": False, "type": "bool"}, + "icmp": {"default": None, "required": False, "type": "bool"}, + "icmp_redirect_disable": {"default": None, "required": False, "type": "bool"}, + "if_name": {"default": None, "required": False, "type": "str"}, + "interface_description": {"default": None, "required": False, "type": "str"}, + "intrf_mtu": {"default": None, "required": False, "type": "int"}, + "ip": { + "default": None, + "elements": "dict", + "options": { + "addr": {"default": None, "required": True, "type": "str"}, + "mac": {"default": None, "required": True, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "ip_directed_broadcast": {"default": None, "required": False, "type": "bool"}, + "iperf_server": {"default": None, "required": False, "type": "str"}, + "ipv4_address": {"default": None, "required": False, "type": "str"}, + "ipv6_address": {"default": None, "required": False, "type": "str"}, + "ipv6_vrrp": { + "default": None, + "elements": "dict", + "options": { + "grp_id": {"default": None, "required": True, "type": "int"}, + "ipv6": { + "default": None, + "elements": "dict", + "options": { + "ipv6_link_local": {"default": None, "required": True, "type": "str"}, + "prefix": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "priority": {"default": None, "required": False, "type": "int"}, + "timer": {"default": None, "required": False, "type": "int"}, + "track_omp": {"default": None, "required": False, "type": "bool"}, + "track_prefix_list": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "last_resort_circuit": {"default": None, "required": False, "type": "bool"}, + "load_interval": {"default": None, "required": False, "type": "int"}, + "loopback_interface": {"default": None, "required": False, "type": "str"}, + "low_bandwidth_link": {"default": None, "required": False, "type": "bool"}, + "mac_address": {"default": None, "required": False, "type": "str"}, + "max_control_connections": {"default": None, "required": False, "type": "int"}, + "media_type": {"default": None, "required": False, "type": "str"}, + "mode": {"default": None, "required": False, "type": "str"}, + "mtu": {"default": None, "required": False, "type": "int"}, + "nat": {"default": None, "required": False, "type": "bool"}, + "nat64": {"default": None, "required": False, "type": "bool"}, + "nat66": {"default": None, "required": False, "type": "bool"}, + "nat_choice": {"default": None, "required": False, "type": "str"}, + "nat_range_end": {"default": None, "required": False, "type": "str"}, + "nat_range_start": {"default": None, "required": False, "type": "str"}, + "nat_refresh_interval": {"default": None, "required": False, "type": "int"}, + "netconf": {"default": None, "required": False, "type": "bool"}, + "network_broadcast": {"default": None, "required": False, "type": "bool"}, + "ntp": {"default": None, "required": False, "type": "bool"}, + "ospf": {"default": None, "required": False, "type": "bool"}, + "overload": {"default": None, "required": False, "type": "bool"}, + "per_tunnel_qos": {"default": None, "required": False, "type": "bool"}, + "per_tunnel_qos_aggregator": {"default": None, "required": False, "type": "bool"}, + "period": {"default": None, "required": False, "type": "int"}, + "poe": {"default": None, "required": False, "type": "bool"}, + "port_hop": {"default": None, "required": False, "type": "bool"}, + "prefix_length": {"default": None, "required": False, "type": "int"}, + "propagate_sgt": {"default": None, "required": False, "type": "bool"}, + "qos_adaptive": {"default": None, "required": False, "type": "bool"}, + "qos_map": {"default": None, "required": False, "type": "str"}, + "qos_map_vpn": {"default": None, "required": False, "type": "str"}, + "restrict": {"default": None, "required": False, "type": "bool"}, + "rule_name": {"default": None, "required": False, "type": "str"}, + "secondary_ipv4_address": { + "default": None, + "elements": "dict", + "options": {"address": {"default": None, "required": False, "type": "str"}}, + "required": False, + "type": "list", + }, + "secondary_ipv6_address": { + "default": None, + "elements": "dict", + "options": {"address": {"default": None, "required": False, "type": "str"}}, + "required": False, + "type": "list", + }, + "secondary_region": {"default": None, "required": False, "type": "str"}, + "security_group_tag": {"default": None, "required": False, "type": "int"}, + "service_provider": {"default": None, "required": False, "type": "str"}, + "shaping_rate": {"default": None, "required": False, "type": "int"}, + "shutdown": {"default": False, "required": False, "type": "bool"}, + "snmp": {"default": None, "required": False, "type": "bool"}, + "speed": {"default": None, "required": False, "type": "str"}, + "src_ip": {"default": None, "required": False, "type": "str"}, + "sshd": {"default": None, "required": False, "type": "bool"}, + "static": { + "default": None, + "elements": "dict", + "options": { + "source_ip": {"default": None, "required": True, "type": "str"}, + "source_vpn": {"default": None, "required": False, "type": "int"}, + "static_nat_direction": {"default": "inside", "required": False, "type": "str"}, + "translate_ip": {"default": None, "required": True, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "static_nat66": { + "default": None, + "elements": "dict", + "options": { + "source_prefix": {"default": None, "required": True, "type": "str"}, + "source_vpn_id": {"default": None, "required": False, "type": "int"}, + "translated_source_prefix": {"default": None, "required": True, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "static_port_forward": { + "default": None, + "elements": "dict", + "options": { + "proto": {"default": None, "required": True, "type": "str"}, + "source_ip": {"default": None, "required": True, "type": "str"}, + "source_port": {"default": None, "required": False, "type": "int"}, + "source_vpn": {"default": None, "required": False, "type": "int"}, + "static_nat_direction": {"default": "inside", "required": False, "type": "str"}, + "translate_ip": {"default": None, "required": True, "type": "str"}, + "translate_port": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "stun": {"default": None, "required": False, "type": "bool"}, + "tcp_mss_adjust": {"default": None, "required": False, "type": "int"}, + "tcp_timeout": {"default": None, "required": False, "type": "int"}, + "tloc_encapsulation": { + "default": None, + "elements": "dict", + "options": { + "encap": {"default": None, "required": True, "type": "str"}, + "preference": {"default": None, "required": False, "type": "int"}, + "weight": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "tloc_extension": {"default": None, "required": False, "type": "str"}, + "tracker": {"default": None, "elements": "str", "required": False, "type": "list"}, + "trusted": {"default": None, "required": False, "type": "bool"}, + "tunnel_tcp_mss_adjust": {"default": None, "required": False, "type": "int"}, + "tunnels_bandwidth": {"default": None, "required": False, "type": "int"}, + "udp_timeout": {"default": None, "required": False, "type": "int"}, + "umax": {"default": None, "required": False, "type": "int"}, + "umin": {"default": None, "required": False, "type": "int"}, + "value": {"default": None, "required": False, "type": "str"}, + "vbond_as_stun_server": {"default": None, "required": False, "type": "bool"}, + "vmanage_connection_preference": {"default": None, "required": False, "type": "int"}, + "vrrp": { + "default": None, + "elements": "dict", + "options": { + "address": {"default": None, "required": False, "type": "str"}, + "grp_id": {"default": None, "required": True, "type": "int"}, + "ipv4_secondary": { + "default": None, + "elements": "dict", + "options": {"address": {"default": None, "required": True, "type": "str"}}, + "required": False, + "type": "list", + }, + "priority": {"default": None, "required": False, "type": "int"}, + "timer": {"default": None, "required": False, "type": "int"}, + "tloc_change_pref": {"default": None, "required": False, "type": "bool"}, + "track_omp": {"default": None, "required": False, "type": "bool"}, + "track_prefix_list": {"default": None, "required": False, "type": "str"}, + "tracking_object": { + "default": None, + "elements": "dict", + "options": { + "decrement": {"default": None, "required": True, "type": "int"}, + "name": {"default": None, "required": True, "type": "int"}, + "track_action": {"default": "Decrement", "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "value": {"default": None, "required": True, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "xconnect": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "dict", + } +} diff --git a/plugins/module_utils/feature_templates/omp_vsmart.py b/plugins/module_utils/feature_templates/omp_vsmart.py new file mode 100644 index 0000000..3c52c22 --- /dev/null +++ b/plugins/module_utils/feature_templates/omp_vsmart.py @@ -0,0 +1,20 @@ +omp_vsmart_definition = { + "omp_vsmart": { + "default": None, + "options": { + "advertisement_interval": {"default": None, "required": False, "type": "int"}, + "affinity_group_preference": {"default": False, "required": False, "type": "bool"}, + "discard_rejected": {"default": None, "required": False, "type": "bool"}, + "eor_timer": {"default": None, "required": False, "type": "int"}, + "graceful_restart": {"default": None, "required": False, "type": "bool"}, + "graceful_restart_timer": {"default": None, "required": False, "type": "int"}, + "holdtime": {"default": None, "required": False, "type": "int"}, + "send_backup_paths": {"default": None, "required": False, "type": "bool"}, + "send_path_limit": {"default": None, "required": False, "type": "int"}, + "shutdown": {"default": None, "required": False, "type": "bool"}, + "tloc_color": {"default": False, "required": False, "type": "bool"}, + }, + "required": False, + "type": "dict", + } +} diff --git a/plugins/module_utils/feature_templates/security_vsmart.py b/plugins/module_utils/feature_templates/security_vsmart.py new file mode 100644 index 0000000..d5cafb3 --- /dev/null +++ b/plugins/module_utils/feature_templates/security_vsmart.py @@ -0,0 +1,11 @@ +security_vsmart_definition = { + "security_vsmart": { + "default": None, + "options": { + "protocol": {"default": None, "required": False, "type": "str"}, + "tls_port": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "dict", + } +} diff --git a/plugins/module_utils/feature_templates/system_vsmart.py b/plugins/module_utils/feature_templates/system_vsmart.py new file mode 100644 index 0000000..fa59be1 --- /dev/null +++ b/plugins/module_utils/feature_templates/system_vsmart.py @@ -0,0 +1,74 @@ +system_vsmart_definition = { + "system_vsmart": { + "default": None, + "options": { + "admin_tech_on_failure": {"default": True, "required": False, "type": "bool"}, + "compatible": { + "default": None, + "elements": "dict", + "options": { + "color_1": {"default": None, "required": False, "type": "str"}, + "color_2": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "control_session_pps": {"default": None, "required": False, "type": "int"}, + "controller_group_id": {"default": None, "required": False, "type": "int"}, + "description": {"default": None, "required": False, "type": "str"}, + "device_groups": {"default": None, "elements": "str", "required": False, "type": "list"}, + "dns_cache_timeout": {"default": None, "required": False, "type": "int"}, + "dual_stack_ipv6": { + "default": None, + "options": {"name": {"default": "system_ipv6-strict-control", "required": True, "type": "str"}}, + "required": False, + "type": "raw", + }, + "host_name": { + "default": None, + "options": {"name": {"default": "system_host_name", "required": True, "type": "str"}}, + "required": False, + "type": "raw", + }, + "idle_timeout": {"default": None, "required": False, "type": "int"}, + "incompatible": { + "default": None, + "elements": "dict", + "options": { + "color_1": {"default": None, "required": False, "type": "str"}, + "color_2": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "iptables_enable": {"default": True, "required": False, "type": "bool"}, + "latitude": {"default": None, "required": False, "type": "int"}, + "location": {"default": None, "required": False, "type": "str"}, + "longitude": {"default": None, "required": False, "type": "int"}, + "management_region": {"default": None, "required": False, "type": "bool"}, + "overlay_id": {"default": None, "required": False, "type": "int"}, + "port_hop": {"default": None, "required": False, "type": "bool"}, + "port_offset": {"default": None, "required": False, "type": "int"}, + "region_list_id": {"default": None, "required": False, "type": "int"}, + "site_id": { + "default": None, + "options": {"name": {"default": "system_site_id", "required": True, "type": "str"}}, + "required": False, + "type": "raw", + }, + "system_ip": { + "default": None, + "options": {"name": {"default": "system_system_ip", "required": True, "type": "str"}}, + "required": False, + "type": "raw", + }, + "system_tunnel_mtu": {"default": None, "required": False, "type": "int"}, + "timezone": {"default": "UTC", "required": False, "type": "str"}, + "topology": {"default": None, "elements": "str", "required": False, "type": "list"}, + "track_default_gateway": {"default": True, "required": False, "type": "bool"}, + "track_transport": {"default": True, "required": False, "type": "bool"}, + }, + "required": False, + "type": "dict", + } +} diff --git a/plugins/module_utils/feature_templates/vpn_vsmart.py b/plugins/module_utils/feature_templates/vpn_vsmart.py new file mode 100644 index 0000000..a44cd60 --- /dev/null +++ b/plugins/module_utils/feature_templates/vpn_vsmart.py @@ -0,0 +1,93 @@ +vpn_vsmart_definition = { + "vpn_vsmart": { + "default": None, + "options": { + "dns": { + "default": None, + "elements": "dict", + "options": { + "dns_addr": {"default": None, "required": False, "type": "str"}, + "role": {"default": None, "required": True, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "host": { + "default": None, + "elements": "dict", + "options": { + "hostname": {"default": None, "required": True, "type": "str"}, + "ip": {"default": None, "elements": "str", "required": True, "type": "list"}, + }, + "required": False, + "type": "list", + }, + "name": {"default": None, "required": False, "type": "str"}, + "route_v4": { + "default": None, + "elements": "dict", + "options": { + "distance": {"default": None, "required": False, "type": "int"}, + "next_hop": { + "default": None, + "elements": "dict", + "options": { + "address": {"default": None, "required": False, "type": "str"}, + "distance": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "null0": {"default": None, "required": False, "type": "bool"}, + "prefix": {"default": None, "required": False, "type": "str"}, + "route_interface": { + "default": None, + "options": { + "interface_name": {"default": None, "required": True, "type": "str"}, + "interface_next_hop": { + "default": None, + "elements": "dict", + "options": { + "address": {"default": None, "required": False, "type": "str"}, + "distance": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "list", + }, + }, + "required": False, + "type": "dict", + }, + "vpn": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "route_v6": { + "default": None, + "elements": "dict", + "options": { + "distance": {"default": None, "required": False, "type": "int"}, + "next_hop": { + "default": None, + "elements": "dict", + "options": { + "address": {"default": None, "required": True, "type": "str"}, + "distance": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "null0": {"default": None, "required": False, "type": "bool"}, + "prefix": {"default": None, "required": True, "type": "str"}, + "vpn": {"default": None, "required": False, "type": "int"}, + }, + "required": False, + "type": "list", + }, + "vpn_id": {"default": None, "required": True, "type": "str"}, + }, + "required": False, + "type": "dict", + } +} diff --git a/plugins/module_utils/feature_templates/vpn_vsmart_interface.py b/plugins/module_utils/feature_templates/vpn_vsmart_interface.py new file mode 100644 index 0000000..9c600de --- /dev/null +++ b/plugins/module_utils/feature_templates/vpn_vsmart_interface.py @@ -0,0 +1,52 @@ +vpn_vsmart_interface_definition = { + "vpn_vsmart_interface": { + "default": None, + "options": { + "all": {"default": None, "required": False, "type": "bool"}, + "autonegotiate": {"default": True, "required": False, "type": "bool"}, + "carrier": {"default": None, "required": False, "type": "str"}, + "clear_dont_fragment": {"default": False, "required": False, "type": "bool"}, + "dhcp": {"default": None, "required": False, "type": "bool"}, + "dhcp_distance": {"default": None, "required": False, "type": "int"}, + "dhcp_ipv4_client": {"default": None, "required": False, "type": "bool"}, + "dhcp_ipv6_client": {"default": None, "required": False, "type": "bool"}, + "dhcp_ipv6_distance": {"default": None, "required": False, "type": "int"}, + "dhcp_rapid_commit": {"default": None, "required": False, "type": "bool"}, + "dns": {"default": None, "required": False, "type": "bool"}, + "duplex": {"default": None, "required": False, "type": "str"}, + "flow_control": {"default": None, "required": False, "type": "str"}, + "group": {"default": None, "elements": "int", "required": False, "type": "list"}, + "hello_interval": {"default": None, "required": False, "type": "int"}, + "hello_tolerance": {"default": None, "required": False, "type": "int"}, + "icmp": {"default": None, "required": False, "type": "bool"}, + "if_name": {"default": None, "required": False, "type": "str"}, + "interface_description": {"default": None, "required": False, "type": "str"}, + "ip": { + "default": None, + "elements": "dict", + "options": { + "addr": {"default": None, "required": True, "type": "str"}, + "mac": {"default": None, "required": True, "type": "str"}, + }, + "required": False, + "type": "list", + }, + "ipv4_address": {"default": None, "required": False, "type": "str"}, + "ipv6_address": {"default": None, "required": False, "type": "str"}, + "mac_address": {"default": None, "required": False, "type": "str"}, + "mtu": {"default": None, "required": False, "type": "int"}, + "nat_refresh_interval": {"default": None, "required": False, "type": "int"}, + "netconf": {"default": None, "required": False, "type": "bool"}, + "ntp": {"default": None, "required": False, "type": "bool"}, + "pmtu": {"default": False, "required": False, "type": "bool"}, + "shutdown": {"default": False, "required": False, "type": "bool"}, + "speed": {"default": None, "required": False, "type": "str"}, + "sshd": {"default": None, "required": False, "type": "bool"}, + "stun": {"default": None, "required": False, "type": "bool"}, + "tcp_mss_adjust": {"default": None, "required": False, "type": "int"}, + "value": {"default": None, "required": False, "type": "str"}, + }, + "required": False, + "type": "dict", + } +} diff --git a/plugins/module_utils/filters.py b/plugins/module_utils/filters.py index ffa61f3..2809c9d 100644 --- a/plugins/module_utils/filters.py +++ b/plugins/module_utils/filters.py @@ -3,7 +3,7 @@ import traceback -from catalystwan.endpoints.configuration_device_inventory import DeviceCategory, DeviceDetailsResponse +from catalystwan.endpoints.configuration_device_inventory import DeviceDetailsResponse from catalystwan.session import ManagerHTTPError from catalystwan.typed_list import DataSequence @@ -12,7 +12,7 @@ def get_target_device( module: AnsibleCatalystwanModule, - device_category: DeviceCategory = "controllers", + device_category="all", all_from_category: bool = False, ) -> DataSequence[DeviceDetailsResponse]: """ @@ -21,9 +21,18 @@ def get_target_device( """ target_device = None try: - devices = module.session.endpoints.configuration_device_inventory.get_device_details( - device_category=device_category + controllers = module.session.endpoints.configuration_device_inventory.get_device_details( + device_category="controllers" ) + vedges = module.session.endpoints.configuration_device_inventory.get_device_details(device_category="vedges") + all_devices = controllers + vedges + + if device_category == "all": + devices = all_devices + elif device_category == "controllers": + devices = controllers + elif device_category == "vedges": + devices = vedges except ManagerHTTPError as ex: module.fail_json( msg=f"Could not perform get_device_details action: {str(ex)}", exception=traceback.format_exc() diff --git a/plugins/module_utils/vmanage_module.py b/plugins/module_utils/vmanage_module.py index c20a8d7..b3e855e 100644 --- a/plugins/module_utils/vmanage_module.py +++ b/plugins/module_utils/vmanage_module.py @@ -8,7 +8,6 @@ import urllib3 from ansible.module_utils.basic import AnsibleModule, env_fallback, missing_required_lib -from catalystwan.typed_list import DataSequence from urllib3.exceptions import NewConnectionError, TimeoutError from ..module_utils.logger_config import configure_logger @@ -23,6 +22,7 @@ try: from catalystwan.api.task_status_api import Task from catalystwan.session import ManagerHTTPError, ManagerRequestException, ManagerSession, create_manager_session + from catalystwan.typed_list import DataSequence from catalystwan.vmanage_auth import UnauthorizedAccessError HAS_LIB = True @@ -90,7 +90,7 @@ def params(self) -> Dict: return self.module.params @property - def params_without_none_values(self): + def params_without_none_values(self) -> Dict: """ When passing values to catalystwan endpoints, we don't want to modify state by providing any None values. """ @@ -177,7 +177,7 @@ def send_request_safely( except ManagerHTTPError as ex: self.fail_json( - msg=f"Could not perform '{action_name}' action.\nManager error: {str(ex)} {ex.info}", + msg=f"Could not perform '{action_name}' action.\nManager error: {ex.info}", exception=traceback.format_exc(), ) diff --git a/plugins/modules/cli_templates.py b/plugins/modules/cli_templates.py new file mode 100644 index 0000000..e1b0f85 --- /dev/null +++ b/plugins/modules/cli_templates.py @@ -0,0 +1,192 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + + +DOCUMENTATION = r""" +--- +module: cli_templates +short_description: Manage CLI templates in Cisco SDWAN +version_added: "0.2.0" +description: + - This module allows you to create or delete CLI templates in Cisco SDWAN. +options: + state: + description: + - Whether the CLI template should be present or absent on the Cisco SDWAN. + required: false + type: str + choices: ["present", "absent"] + default: "present" + template_name: + description: + - The name of the CLI template. + required: true + type: str + template_description: + description: + - The description of the CLI template. + required: false + type: str + default: None + config_file: + description: + - The path to the configuration file that contains the CLI template content. + required: false + type: str + aliases: ["running_config_file_path"] +author: + - Arkadiusz Cichon (acichon@cisco.com) +extends_documentation_fragment: + - cisco.catalystwan.device_models_device_template + - cisco.catalystwan.manager_authentication +notes: + - Ensure that the provided credentials have sufficient permissions to manage templates and devices in vManage. +""" + +EXAMPLES = r""" +- name: Using configuration from file, ensure a CLI template is present on vManage + cisco.catalystwan.cli_templates: + state: present + template_name: "MyTemplate" + template_description: "This is a CLI template for device configuration" + device_model: "ISR4451" + config_file: "/path/to/config_file.txt" + manager_credentials: ... + +- name: Remove a CLI template from vManage + cisco.catalystwan.cli_templates: + state: absent + template_name: "MyTemplate" + manager_credentials: ... +""" + +RETURN = r""" +msg: + description: A message describing the result of the operation. + returned: always + type: str + sample: "Created template MyTemplate: MyTemplate. Template id: abc123" +changed: + description: A boolean flag indicating if any changes were made. + returned: always + type: bool + sample: true +template_id: + description: The ID of the template that was created or modified. + returned: when a template is created + type: str + sample: "abc123" +""" + +from typing import Literal, Optional, get_args + +from catalystwan.api.template_api import CLITemplate +from catalystwan.models.common import DeviceModel +from catalystwan.models.templates import DeviceTemplateInformation +from catalystwan.session import ManagerHTTPError +from catalystwan.typed_list import DataSequence + +from ..module_utils.result import ModuleResult +from ..module_utils.vmanage_module import AnsibleCatalystwanModule + +State = Literal["present", "absent"] + + +def run_module(): + module_args = dict( + state=dict( + type=str, + choices=list(get_args(State)), + default="present", + ), + template_name=dict(type="str", required=True), + template_description=dict(type="str", default=None), + device_model=dict(type="str", aliases=["device_type"], choices=list(get_args(DeviceModel)), default=None), + config_file=dict(type="str", aliases=["running_config_file_path"]), + ) + result = ModuleResult() + + module = AnsibleCatalystwanModule( + argument_spec=module_args, + required_if=[ + ( + "state", + "present", + ( + "template_name", + "template_description", + "device_model", + ), + ), + ( + "state", + "absent", + ("template_name",), + ), + ], + ) + + template_name = module.params.get("template_name") + + all_templates: DataSequence[DeviceTemplateInformation] = module.get_response_safely( + module.session.api.templates.get, template=CLITemplate + ) + target_template: Optional[DeviceTemplateInformation] = all_templates.filter(name=template_name) + + if module.params.get("state") == "present": + # Code for checking if template name exists already + if target_template: + module.logger.debug(f"Detected existing template:\n{target_template}\n") + result.msg = ( + f"Template with name {template_name} already present on vManage, skipping create template operation." + ) + else: + cli_template = CLITemplate( + template_name=template_name, + template_description=module.params.get("template_description"), + device_model=module.params.get("device_model"), + ) + cli_template.load_from_file(file=module.params.get("config_file")) + + module.logger.debug(f"Prepared template for sending to vManage, template configuration:\n{cli_template}\n") + try: + template_id: str = module.session.api.templates.create( + template=cli_template, debug=module.params.get("debug") + ) + except ManagerHTTPError as ex: + module.fail_json( + msg=f"Could not perform create CLI Template {template_name}.\nManager error: {ex.info}" + ) + result.changed = True + result.msg += f"Created template {template_name}: {cli_template.template_name}. Template id: {template_id}" + + if module.params.get("state") == "absent": + if target_template: + module.send_request_safely( + result, + action_name="Delete Template", + send_func=module.session.api.templates.delete, + template=CLITemplate, + name=template_name, + ) + result.changed = True + result.msg = f"Deleted template {template_name}" + else: + module.logger.debug(f"Template '{target_template}' not presend in list of Templates on vManage.") + result.msg = ( + f"Template {template_name} not presend in list of CLI Templates on vManage. " + "skipping delete template operation." + ) + + module.exit_json(**result.model_dump(mode="json")) + + +def main(): + run_module() + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/device_templates.py b/plugins/modules/device_templates.py new file mode 100644 index 0000000..c221873 --- /dev/null +++ b/plugins/modules/device_templates.py @@ -0,0 +1,296 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + + +DOCUMENTATION = r""" +--- +module: Device_templates +short_description: Manage Device Templates on vManage. +version_added: "0.2.0" +description: + - This module allows you to create, delete, attach and detach Device Templates +options: + state: + description: + - Desired state for the template. + - 0(state=present) is equivalent of create template in GUI + type: str + choices: ["absent", "present", "attached"] + default: "present" + template_name: + description: + - The name for the Feature Template. + type: str + required: true + template_description: + description: + - Description for the Feature Template. + type: str + required: true + device_role: + description: + - The device role. Applicable to all devices except 'vManage' and 'vSmart' + required: false + default: null + type: str + choices: ["service-node", "sdwan-edge"] + general_templates: + description: + - List of names of Feature Templates to be included in Device Template + required: false + default: null + type: list + elements: dict + suboptions: + name: + description: + - The name of the template + required: true + type: str + subtemplates: + description: + - List of names of the subtemplates to be attached to General template + required: false + default: null + type: list + elements: str + timeout_seconds: + description: + - The timeout in seconds for attaching the template. Default is 300. + type: int + hostname: + description: + - Hostname of the device to attach template. Available only for 0(state=attached). + type: str + device_specific_vars: + description: + - For parameters in a feature template that you configure as device-specific, + when you attach a device template to a device, Cisco vManage prompts you for the values to use + for these parameters. + type: raw +author: + - Arkadiusz Cichon (acichon@cisco.com) +extends_documentation_fragment: + - cisco.catalystwan.device_models_device_template + - cisco.catalystwan.manager_authentication +notes: + - Ensure that the provided credentials have sufficient permissions to manage templates and devices in vManage. +""" + +EXAMPLES = r""" +- name: Ensure a device template is present on vManage + cisco.catalystwan.device_templates: + state: present + template_name: "MyDeviceTemplate" + template_description: "This is a device template for device configuration" + device_type: "ISR4451" + device_role: "sdwan-edge" + general_templates: + - "Template1" + - "Template2" + manager_credentials: ... + +- name: Attach a device template to a device with a specific hostname + cisco.catalystwan.device_templates: + state: attached + template_name: "MyDeviceTemplate" + hostname: "device-hostname" + timeout_seconds: 600 + manager_credentials: ... + +- name: Remove a device template from vManage + cisco.catalystwan.device_templates: + state: absent + template_name: "MyDeviceTemplate" + manager_credentials: ... +""" + +RETURN = r""" +msg: + description: A message describing the result of the operation. + returned: always + type: str + sample: "Created template MyDeviceTemplate: MyDeviceTemplate" + +changed: + description: A boolean flag indicating if any changes were made. + returned: always + type: bool + sample: true +""" + +from typing import Literal, Optional, get_args + +from catalystwan.api.template_api import DeviceTemplate, GeneralTemplate +from catalystwan.dataclasses import Device +from catalystwan.exceptions import TemplateNotFoundError +from catalystwan.models.common import DeviceModel +from catalystwan.models.templates import DeviceTemplateInformation +from catalystwan.session import ManagerHTTPError +from catalystwan.typed_list import DataSequence + +from ..module_utils.result import ModuleResult +from ..module_utils.vmanage_module import AnsibleCatalystwanModule + +State = Literal["present", "absent", "attached"] + + +def run_module(): + module_args = dict( + state=dict( + type=str, + choices=list(get_args(State)), + default="present", + ), + template_name=dict(type="str", required=True), + template_description=dict(type="str", default=None), + device_type=dict(type="str", aliases=["device_model"], choices=list(get_args(DeviceModel)), default=None), + device_role=dict(type="str", choices=["sdwan-edge", "service-node"], default="sdwan-edge"), + general_templates=dict( + type="list", + elements="dict", + options=dict( + name=dict(type="str", required=True), + subtemplates=dict(type="list", elements="str", default=[]), + ), + default=[], + ), + timeout_seconds=dict(type="int", default=300), + hostname=dict(type="str"), + device_specific_vars=dict(type="list", elements="dict"), + ) + result = ModuleResult() + + module = AnsibleCatalystwanModule( + argument_spec=module_args, + required_if=[ + ( + "state", + "present", + ( + "template_name", + "template_description", + "device_type", + ), + ), + ( + "state", + "absent", + ("template_name",), + ), + ( + "state", + "attached", + ( + "template_name", + "hostname", + ), + ), + ], + ) + + template_name = module.params.get("template_name") + + all_templates: DataSequence[DeviceTemplateInformation] = module.get_response_safely( + module.session.api.templates.get, template=DeviceTemplate + ) + target_template: Optional[DeviceTemplateInformation] = all_templates.filter(name=template_name) + + if module.params.get("state") == "present": + # Code for checking if template name exists already + if target_template: + module.logger.debug(f"Detected existing template:\n{target_template}\n") + result.msg = ( + f"Template with name {template_name} already present on vManage, skipping create template operation." + ) + else: + general_templates = [] + for template in module.params.get("general_templates"): + sub_templates = [GeneralTemplate(name=sub) for sub in template.get("subtemplates", [])] + general_templates.append(GeneralTemplate(name=template["name"], subTemplates=sub_templates)) + + device_template = DeviceTemplate( + template_name=template_name, + template_description=module.params.get("template_description"), + device_type=module.params.get("device_type"), + device_role=module.params.get("device_role"), + general_templates=general_templates, + ) + + module.logger.debug( + f"Prepared template for sending to vManage, template configuration:\n{device_template}\n" + ) + try: + module.session.api.templates.create(template=device_template, debug=module.params.get("debug")) + except ManagerHTTPError as ex: + module.fail_json( + msg=f"Could not perform add Feature Template {template_name}.\nManager error: {ex.info}" + ) + result.changed = True + result.msg += f"Created template {template_name}: {device_template}" + + if module.params.get("state") == "attached": + hostname = module.params.get("hostname") + device: DataSequence[Device] = ( + module.get_response_safely(module.session.api.devices.get).filter(hostname=hostname).single_or_default() + ) + + if not device: + module.fail_json(f"No devices with hostname found, hostname provided: {hostname}") + try: + response = None + if module.params.get("device_specific_vars"): + device_specific_vars = {k: v for d in module.params.get("device_specific_vars") for k, v in d.items()} + response = module.session.api.templates.attach( + name=template_name, + device=device, + device_specific_vars=device_specific_vars, + timeout_seconds=module.params.get("timeout_seconds"), + ) + else: + response = module.session.api.templates.attach( + name=template_name, + device=device, + timeout_seconds=module.params.get("timeout_seconds"), + ) + if not response: + module.fail_json(f"Failed to attach device template: {template_name}") + result.changed = True + result.msg = f"Attached template {template_name} to device: {hostname}" + except ManagerHTTPError as ex: + module.fail_json(msg=f"Could not perform attach Template {template_name}.\nManager error: {ex.info}") + except TemplateNotFoundError as ex: + module.fail_json(msg=f"Template with name: {template_name} doesn't exist. \nOriginal error: {ex}") + except TypeError as ex: + module.fail_json(msg=f"{ex}") + + if module.params.get("state") == "absent": + if target_template: + module.send_request_safely( + result, + action_name="Delete Template", + send_func=module.session.api.templates.delete, + template=DeviceTemplate, + name=template_name, + ) + result.changed = True + result.msg = f"Deleted template {template_name}" + else: + module.logger.debug(f"Template '{target_template}' not presend in list of Device Templates on vManage.") + result.msg = ( + f"Template {template_name} not presend in list of Device Templates on vManage. " + "skipping delete template operation." + ) + + module.exit_json(**result.model_dump(mode="json")) + + +def main(): + run_module() + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/device_templates_info.py b/plugins/modules/device_templates_info.py new file mode 100644 index 0000000..0811d2c --- /dev/null +++ b/plugins/modules/device_templates_info.py @@ -0,0 +1,267 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + + +DOCUMENTATION = r""" +--- +module: Device_templates_info +short_description: Get information about Device Templates on vManage. +version_added: "0.2.0" +description: + - This module allows you to get Device Templates Info from vManage. + - Device Templates can be filtered by Device Templates Info key:values. +options: + filters: + description: + - A dictionary of filters used to select Device Templates info. + type: dict + required: false + suboptions: + template_type: + description: + - The type of template, eg. "system-vsmart + required: false + default: null + type: str + device_type: + description: + - The device type of the template + required: false + default: null + type: list + elements: str + name: + description: + - The name of the Device Template. + required: false + default: null + type: str + description: + description: + - Description of the Device Template. + required: false + default: null + type: str + version: + description: + - Version of the Device Template. + required: false + default: null + type: str + factory_default: + description: + - If template is Factory Default template. + required: false + default: null + type: bool + template_definiton: + description: + - The definiton of Device Template. + required: false + default: null + type: str + devices_attached: + description: + - Number of attached devices. + required: false + default: null + type: int + draft_mode: + description: + - The draft mode of template. + required: false + default: null + type: str + device_role: + description: + - The device role. + required: false + default: null + type: str + id: + description: + - Device Template ID. + required: false + default: null + type: str + last_updated_on: + description: + - Last Updated on value. + required: false + default: null + type: int + last_updated_by: + description: + - Last Updated by value. + required: false + default: null + type: str + resource_group: + description: + - Resource Group value. + required: false + default: null + type: str + backup: + description: + - This argument triggers the module to back up the filtered Device Templates. + Device Template backup is dumped json payload with template definition. + Without specified backup_dir_path, it saves to the playbook's root "backup" folder + or the role's root if within an Ansible role. The folder is created if it doesn't exist. + type: bool + default: false + backup_dir_path: + description: + - Directory to store the backup. It's created if missing. Defaults to a 'backup' folder in the current directory. + type: path +author: + - Arkadiusz Cichon (acichon@cisco.com) +extends_documentation_fragment: + - cisco.catalystwan.manager_authentication +notes: + - Ensure that the provided credentials have sufficient permissions to manage templates and devices in vManage. +""" + +EXAMPLES = r""" +- name: Get all Non-Default Device Templates available + cisco.catalystwan.device_templates_info: + filters: + factory_default: false + manager_credentials: + ... + register: device_templates +""" + +RETURN = r""" +template_info: + description: A list of dictionaries of templates info + type: list + returned: on success + sample: | + templates_info: + - configType: template + deviceRole: sdwan-edge + deviceType: vedge-C8000V + devicesAttached: 0 + draftMode: Disabled + factoryDefault: false + lastUpdatedBy: example_admin + lastUpdatedOn: 1715270833776 + resourceGroup: global + templateAttached: 11 + templateClass: cedge + templateDescription: xd + templateId: xxx-xxx-xxx + templateName: xd +msg: + description: Messages that indicate actions taken or any errors that have occurred. + type: str + returned: always + sample: "Successfully fetched information about template: trial-template" +changed: + description: Indicates whether any change was made. + type: bool + returned: always + sample: false +""" + +import json +import traceback +from pathlib import Path, PurePath +from typing import Dict, List, Optional + +from catalystwan.api.template_api import DeviceTemplate +from catalystwan.models.templates import DeviceTemplateInformation +from catalystwan.session import ManagerHTTPError +from catalystwan.typed_list import DataSequence +from pydantic import BaseModel, Field + +from ..module_utils.result import ModuleResult +from ..module_utils.vmanage_module import AnsibleCatalystwanModule + + +class BackupPathModel(BaseModel): + hostname: str + filename: str + backup_path: str + + +class ExtendedModuleResult(ModuleResult): + templates_info: Optional[Dict] = Field(default={}) + backup_paths: Optional[List[BackupPathModel]] = Field(default=[]) + + +def run_module(): + module_args = dict( + filters=dict(type="dict", default=None, required=False), + backup=dict(type=bool, default=False), + backup_dir_path=dict(type="path", default=PurePath(Path.cwd() / "backup")), + ) + result = ExtendedModuleResult() + + module = AnsibleCatalystwanModule(argument_spec=module_args) + + filters = module.params.get("filters") + filtered_templates = DataSequence(DeviceTemplateInformation) + + all_templates: DataSequence[DeviceTemplateInformation] = module.get_response_safely( + module.session.api.templates.get, template=DeviceTemplate + ) + + if filters: + filtered_templates = all_templates.filter(**filters) + if filtered_templates: + module.logger.info(f"All Device Templates filtered with filters: {filters}:\n{filtered_templates}") + result.msg = "Succesfully got all requested Device Templates Info from vManage" + result.templates_info = [template for template in filtered_templates] + else: + module.logger.warning(msg=f"Device templates filtered with `{filters}` not present.") + result.msg = f"Device templates filtered with `{filters}` not present on vManage." + else: + result.msg = "Succesfully got all Device Templates Info from vManage" + result.templates_info = [template for template in all_templates] + + if module.params.get("backup"): + backup_dir_path: Path = Path(module.params.get("backup_dir_path")) + module.logger.info(f"{backup_dir_path}") + try: + backup_dir_path.mkdir(parents=True, exist_ok=True) + except OSError as ex: + module.fail_json(msg=f"Cannot create or find directory: {backup_dir_path}, exception: {ex.strerror}") + + templates_to_backup = filtered_templates if filtered_templates else all_templates + if templates_to_backup: + for template in templates_to_backup: + try: + template_payload = module.session.get(f"dataservice/template/device/object/{template.id}").json() + except ManagerHTTPError as ex: + module.fail_json( + msg=( + f"Could not call get DeviceTemplate payload for template with name: {template.name}. " + f"\nManager error: {ex.info}" + ), + exception=traceback.format_exc(), + ) + filename = f"{template.name}.json" + backup_path = f"{backup_dir_path}/{filename}" + with open(backup_path, "w", encoding="utf-8") as file: + json.dump(template_payload, file, ensure_ascii=False, indent=4) + result.backup_paths.append( + BackupPathModel(hostname=template.name, backup_path=backup_path, filename=filename) + ) + result.msg = f"Succesfully saved Device Template payload to file: {backup_path}" + else: + module.module.warn(f"No Device Templates found based on filters: {filters}") + + module.exit_json(**result.model_dump(mode="json")) + + +def main(): + run_module() + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/device_templates_recovery.py b/plugins/modules/device_templates_recovery.py new file mode 100644 index 0000000..dbc2aed --- /dev/null +++ b/plugins/modules/device_templates_recovery.py @@ -0,0 +1,197 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: device_templates_recovery +short_description: Backup and restore Device Templates +version_added: "0.2.0" +description: + - This module allows you to backup and restore Device Templates. + - With 0(mode=backup), it exports Device Templates (with Feature Templates and Policies) + and store them to tar archive. + - With 0(mode=restore), it extracts the templates from a tar archive, loads the JSON data for device, + feature, and policy templates, and then processes them to create or update the templates. + Templates will be extracted to Path(Path.cwd() / "templates") location. + - If 0(backup_dir_path) already exists, it will be removed and new empty director will be created. +options: + mode: + description: + - Desired recovery operation. + type: str + choices: ["backup", "restore"] + default: "backup" + backup_dir_path: + description: + - With 0(mode=backup), directory to store the backup. It's created if missing. + Defaults to a 'default_templates' folder in the current directory. + - With 0(mode=restore), directory containing the tar archive of templates. + type: path + filters: + description: + - A dictionary of filters used to select Device Templates to backup. + type: dict + required: false + suboptions: + template_type: + description: + - The type of template, eg. "system-vsmart + required: false + default: null + type: str + device_type: + description: + - The device type of the template + required: false + default: null + type: list + elements: str + name: + description: + - The name of the Device Template. + required: false + default: null + type: str + description: + description: + - Description of the Device Template. + required: false + default: null + type: str + version: + description: + - Version of the Device Template. + required: false + default: null + type: str + factory_default: + description: + - If template is Factory Default template. + required: false + default: false + type: bool + template_definiton: + description: + - The definiton of Device Template. + required: false + default: null + type: str + devices_attached: + description: + - Number of attached devices. + required: false + default: null + type: int + draft_mode: + description: + - The draft mode of template. + required: false + default: null + type: str + device_role: + description: + - The device role. + required: false + default: null + type: str + id: + description: + - Device Template ID. + required: false + default: null + type: str + last_updated_on: + description: + - Last Updated on value. + required: false + default: null + type: int + last_updated_by: + description: + - Last Updated by value. + required: false + default: null + type: str + resource_group: + description: + - Resource Group value. + required: false + default: null + type: str +author: + - Arkadiusz Cichon (acichon@cisco.com) +extends_documentation_fragment: + - cisco.catalystwan.manager_authentication +notes: + - Ensure that the provided credentials have sufficient permissions to manage templates and devices in vManage. +""" + +EXAMPLES = r""" +""" + +RETURN = r""" +""" + +from pathlib import Path, PurePath + +from catalystwan.session import ManagerHTTPError +from catalystwan.workflows import backup_restore_device_templates + +from ..module_utils.result import ModuleResult +from ..module_utils.vmanage_module import AnsibleCatalystwanModule + + +def run_module(): + module_args = dict( + mode=dict( + type=str, + choices=list(["backup", "restore"]), + default="backup", + ), + filters=dict(type="dict", default={"factory_default": False}, required=False), + backup_dir_path=dict(type="path", default=PurePath(Path.cwd() / "backup")), + ) + result = ModuleResult() + + module = AnsibleCatalystwanModule(argument_spec=module_args) + + filters = module.params.get("filters") + backup_dir_path: Path = Path(module.params.get("backup_dir_path")) + + if module.params.get("mode") == "backup": + try: + backup_restore_device_templates.export_templates( + session=module.session, + templates_directory=backup_dir_path, + filters=filters, + force_existing_dir_removal=True, + ) + except ManagerHTTPError as ex: + module.fail_json(msg=f"Could not perform Backup of Device Templates.\nManager error: {ex.info}") + result.changed = True + result.msg += f"Successfully exported and archived Device Templates to directory: {backup_dir_path}" + result.msg += "See catalystwan log file for more details." + + if module.params.get("mode") == "restore": + try: + backup_restore_device_templates.import_templates( + session=module.session, templates_directory=backup_dir_path + ) + except ManagerHTTPError as ex: + module.fail_json(msg=f"Could not perform Import of Device Templates.\nManager error: {ex.info}") + result.changed = True + result.msg += f"Successfully imported Device Templates to Manager from directory: {backup_dir_path}" + result.msg += "See catalystwan log file for more details." + + module.exit_json(**result.model_dump(mode="json")) + + +def main(): + run_module() + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/devices_info.py b/plugins/modules/devices_info.py index e32e058..5e56406 100644 --- a/plugins/modules/devices_info.py +++ b/plugins/modules/devices_info.py @@ -12,22 +12,42 @@ description: - This module retrieves details about devices in vManage. - It can filter the retrieved device information based on specified criteria. + - This module supports backup of running-config from devices. Available for all or filtered devices. options: device_category: description: - Category of devices to retrieve information for. type: str - choices: ["controllers", "vedges"] + choices: ["controllers", "vedges", "all"] + default: all + details: + description: + - This argument triggers the module to collect device details info. + type: bool + default: true filters: description: - Dictionary of filter key-value pairs to apply on the device details. type: dict default: None + backup: + description: + - This argument triggers the module to back up the filtered device's current running-config. + Without specified backup_dir_path, it saves to the playbook's root "backup" folder + or the role's root if within an Ansible role. The folder is created if it doesn't exist. + type: bool + default: false + backup_dir_path: + description: + - Directory to store the backup. It's created if missing. Defaults to a 'backup' folder in the current directory. + type: path author: - Arkadiusz Cichon (acichon@cisco.com) notes: - - The 'filters' option allows for specifying filtering criteria such as device model, status, etc. + - The C(filters) option allows for specifying filtering criteria such as device model, status, etc. + - The C(backup) option doesn't allow to specify backup file path, it only allows to specify directory + Backup files are always stored in format of f"{base_filename}_{timestamp} extends_documentation_fragment: - cisco.catalystwan.manager_authentication @@ -72,45 +92,102 @@ model: "vedge-1000" status: "active" """ - +from datetime import datetime +from pathlib import Path, PurePath from typing import List, Optional +from catalystwan.dataclasses import Device from catalystwan.endpoints.configuration_device_inventory import DeviceDetailsResponse from catalystwan.typed_list import DataSequence -from pydantic import Field +from pydantic import BaseModel, Field from ..module_utils.filters import get_target_device from ..module_utils.result import ModuleResult from ..module_utils.vmanage_module import AnsibleCatalystwanModule +class BackupPathModel(BaseModel): + hostname: str + filename: str + backup_path: str + + class ExtendedModuleResult(ModuleResult): devices: Optional[List] = Field(default=[]) + backup_paths: Optional[List[BackupPathModel]] = Field(default=[]) def run_module(): module_args = dict( device_category=dict( type=str, - choices=["controllers", "vedges"], + choices=["controllers", "vedges", "all"], + default="all", ), + details=dict(type=bool, default=True), filters=dict(type=dict, default=None), + backup=dict(type=bool, default=False), + backup_dir_path=dict(type="path", default=PurePath(Path.cwd() / "backup")), ) - module = AnsibleCatalystwanModule(argument_spec=module_args) + module = AnsibleCatalystwanModule( + argument_spec=module_args, + mutually_exclusive=[ + ("details", "backup"), + ("details", "backup_dir_path"), + ], + ) result = ExtendedModuleResult() - devices = get_target_device(module, device_category=module.params.get("device_category"), all_from_category=True) + details = module.params.get("details") + filters = module.params.get("filters") + backup = module.params.get("backup") + backup_dir_path: Path = Path(module.params.get("backup_dir_path")) + + devices: DataSequence[DeviceDetailsResponse] = get_target_device( + module, device_category=module.params.get("device_category"), all_from_category=True + ) if not devices: + module.module.warn("No devices found") module.exit_json(**result.model_dump(mode="json")) - if module.params.get("filters"): - filtered_devices: DataSequence[DeviceDetailsResponse] = devices.filter(**module.params.get("filters")) - module.logger.debug(f"All filtered_devices: {filtered_devices}") - result.devices = [dev.model_dump(mode="json") for dev in filtered_devices] - else: - result.devices = [dev.model_dump(mode="json") for dev in devices] + if details and not backup: + if filters: + filtered_devices: DataSequence[DeviceDetailsResponse] = devices.filter(**filters) + if filtered_devices: + module.logger.debug(f"All filtered_devices: {filtered_devices}") + result.devices = [dev.model_dump(mode="json") for dev in filtered_devices] + else: + module.module.warn(f"No devices found based on filters: {filters}") + else: + result.devices = [dev.model_dump(mode="json") for dev in devices] + + if backup: + module.logger.info(f"{backup_dir_path}") + try: + backup_dir_path.mkdir(parents=True, exist_ok=True) + except OSError as ex: + module.fail_json(msg=f"Cannot create or find directory: {backup_dir_path}, exception: {ex.strerror}") + + if filters: + devices: DataSequence[Device] = module.get_response_safely(module.session.api.devices.get).filter(**filters) + else: + devices: DataSequence[Device] = module.get_response_safely(module.session.api.devices.get) + + if devices: + for device in devices: + rcfg = module.get_response_safely(module.session.api.templates.load_running, device=device) + timestamp = datetime.now().strftime("%d-%m-%Y-%H-%M") + filename = f"{device.hostname}_{timestamp}.txt" + backup_path = f"{backup_dir_path}/{filename}" + rcfg.save_as(backup_path) + result.backup_paths.append( + BackupPathModel(hostname=device.hostname, backup_path=backup_path, filename=filename) + ) + result.msg = f"Succesfully saved running configuration to file: {backup_path}" + else: + module.module.warn(f"No devices found based on filters: {filters}") module.exit_json(**result.model_dump(mode="json")) diff --git a/plugins/modules/feature_templates.py b/plugins/modules/feature_templates.py new file mode 100644 index 0000000..56f26b8 --- /dev/null +++ b/plugins/modules/feature_templates.py @@ -0,0 +1,264 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: vmanage_feature_template +short_description: Manage feature templates for Cisco vManage SD-WAN +version_added: "0.2.0" +description: + - This module can be used to create, modify, and delete feature templates in Cisco vManage SD-WAN. + - The feature template configuration is defined via Python Pydantic models. +options: + state: + description: + - Desired state for the template. + - 0(state=present) is equivalent of create template in GUI + type: str + choices: ["absent", "present", "modified"] + default: "present" + template_name: + description: + - The name for the Feature Template. + type: str + required: true + template_description: + description: + - Description for the Feature Template. + type: str + required: false + device_specific_variables: + description: + - Dictionary containing device specific variables names to be defined in template. + type: dict + required: false + debug: + description: + - If to write payload of created template and response from vmanage as json to file. + - Files will be written to C(CWD) as I("payload_{template.type}.json") and I("response_{template.type}.json"). + type: bool + default: false +extends_documentation_fragment: + - cisco.catalystwan.feature_template_aaa + - cisco.catalystwan.feature_template_cisco_aaa + - cisco.catalystwan.feature_template_cisco_banner + - cisco.catalystwan.feature_template_cisco_bfd + - cisco.catalystwan.feature_template_cisco_logging + - cisco.catalystwan.feature_template_cisco_ntp + - cisco.catalystwan.feature_template_cisco_omp + - cisco.catalystwan.feature_template_cisco_ospf + - cisco.catalystwan.feature_template_cisco_secure_internet_gateway + - cisco.catalystwan.feature_template_cisco_snmp + - cisco.catalystwan.feature_template_cisco_system + - cisco.catalystwan.feature_template_cisco_vpn + - cisco.catalystwan.feature_template_cisco_vpn_interface + - cisco.catalystwan.feature_template_omp_vsmart + - cisco.catalystwan.feature_template_security_vsmart + - cisco.catalystwan.feature_template_system_vsmart + - cisco.catalystwan.feature_template_vpn_vsmart_interface + - cisco.catalystwan.feature_template_vpn_vsmart + - cisco.catalystwan.device_models_feature_template + - cisco.catalystwan.manager_authentication +author: + - Arkadiusz Cichon (acichon@cisco.com) +""" + + +from typing import Dict, Final, Literal, Optional, get_args + +from catalystwan.api.template_api import FeatureTemplate +from catalystwan.api.templates.device_variable import DeviceVariable +from catalystwan.api.templates.models.supported import available_models +from catalystwan.models.common import DeviceModel +from catalystwan.models.templates import FeatureTemplateInformation +from catalystwan.session import ManagerHTTPError +from catalystwan.typed_list import DataSequence +from pydantic import BaseModel, ConfigDict, Field + +from ..module_utils.feature_templates.aaa import aaa_definition +from ..module_utils.feature_templates.cisco_aaa import cisco_aaa_definition +from ..module_utils.feature_templates.cisco_banner import cisco_banner_definition +from ..module_utils.feature_templates.cisco_bfd import cisco_bfd_definition +from ..module_utils.feature_templates.cisco_logging import cisco_logging_definition +from ..module_utils.feature_templates.cisco_ntp import cisco_ntp_definition +from ..module_utils.feature_templates.cisco_omp import cisco_omp_definition +from ..module_utils.feature_templates.cisco_ospf import cisco_ospf_definition +from ..module_utils.feature_templates.cisco_secure_internet_gateway import cisco_secure_internet_gateway_definition +from ..module_utils.feature_templates.cisco_snmp import cisco_snmp_definition +from ..module_utils.feature_templates.cisco_system import cisco_system_definition +from ..module_utils.feature_templates.cisco_vpn import cisco_vpn_definition +from ..module_utils.feature_templates.cisco_vpn_interface import cisco_vpn_interface_definition +from ..module_utils.feature_templates.omp_vsmart import omp_vsmart_definition +from ..module_utils.feature_templates.security_vsmart import security_vsmart_definition +from ..module_utils.feature_templates.system_vsmart import system_vsmart_definition +from ..module_utils.feature_templates.vpn_vsmart import vpn_vsmart_definition +from ..module_utils.feature_templates.vpn_vsmart_interface import vpn_vsmart_interface_definition +from ..module_utils.result import ModuleResult +from ..module_utils.vmanage_module import AnsibleCatalystwanModule + +ALLOW: Final[str] = "allow" + + +class Values(BaseModel): + model_config = ConfigDict(extra=ALLOW, populate_by_name=True) + + +class ExtendedModuleResult(ModuleResult): + templates_info: Optional[Dict] = Field(default={}) + + +State = Literal["present", "modified", "absent"] + + +def run_module(): + module_args = dict( + state=dict( + type=str, + choices=list(get_args(State)), + default="present", + ), + template_name=dict(type="str", required=True), + template_description=dict(type="str", default=None), + device_models=dict(type="list", choices=list(get_args(DeviceModel)), default=[]), + debug=dict(type="bool", default=False), + device_specific_variables=dict(type="raw", default={}), + # device=dict(type="str", default=None), # For this we need to think how to pass devices + **aaa_definition, + **cisco_aaa_definition, + **cisco_banner_definition, + **cisco_bfd_definition, + **cisco_logging_definition, + **cisco_ntp_definition, + **cisco_omp_definition, + **cisco_ospf_definition, + **cisco_secure_internet_gateway_definition, + **cisco_snmp_definition, + **cisco_system_definition, + **cisco_vpn_interface_definition, + **cisco_vpn_definition, + **omp_vsmart_definition, + **security_vsmart_definition, + **system_vsmart_definition, + **vpn_vsmart_definition, + **vpn_vsmart_interface_definition, + ) + + result = ExtendedModuleResult() + + module = AnsibleCatalystwanModule( + argument_spec=module_args, + required_if=[ + ( + "state", + "present", + ( + "template_name", + "template_description", + "device_models", + ), + ), + ( + "modified", + "modified", + ( + "template_name", + "template_description", + "device_models", + ), + ), + ( + "state", + "absent", + ("template_name",), + ), + ], + ) + # Verify if we are dealing with one or more templates + template_name = module.params.get("template_name") + device_specific_variables: Dict = module.params.get("device_specific_variables") + module.logger.info(f"Module input: \n{module.params}\n") + + all_templates: DataSequence[FeatureTemplateInformation] = module.get_response_safely( + module.session.api.templates.get, template=FeatureTemplate + ) + target_template: Optional[FeatureTemplateInformation] = all_templates.filter(name=template_name) + + if module.params.get("state") == "present": + # Code for checking if template name exists already + if target_template: + module.logger.debug(f"Detected existing template:\n{target_template}\n") + result.msg = ( + f"Template with name {template_name} already present on vManage, skipping create template operation." + ) + else: + for model_name, model_module in available_models.items(): + if model_name in module.params.keys(): + if module.params[model_name] is not None: + module.logger.debug(f"Template input:\n{module.params_without_none_values[model_name]}\n") + # Perform action with template + + configuration: Dict = module.params_without_none_values[model_name] + + # Check if any device_specific_variables defined and use them in template + if device_specific_variables: + _dsv = Values() + for key, value in device_specific_variables.items(): + dev_value = DeviceVariable(name=value) + setattr(_dsv, key, dev_value) + + for field, value in configuration.items(): + if value == "device_specific_variable": + configuration[field] = _dsv.model_extra[field] + + template = model_module( + template_name=template_name, + template_description=module.params.get("template_description"), + device_models=module.params.get("device_models"), + **configuration, + ) + + module.logger.debug( + f"Prepared template for sending to vManage, template configuration:\n{template}\n" + ) + try: + module.session.api.templates.create(template=template, debug=module.params.get("debug")) + except ManagerHTTPError as ex: + module.fail_json( + msg=f"Could not perform add Feature Template {template_name}.\nManager error: {ex.info}" + ) + result.changed = True + result.msg += f"Created template {model_name}: {template}" + + if module.params.get("state") == "absent": + if target_template: + module.send_request_safely( + result, + action_name="Delete Template", + send_func=module.session.api.templates.delete, + template=FeatureTemplate, + name=template_name, + ) + result.changed = True + result.msg = f"Deleted template {template_name}" + else: + module.logger.debug(f"Template '{target_template}' not presend in list of Feature Templates on vManage.") + result.msg = ( + f"Template {template_name} not presend in list of Feature Templates on vManage, " + "skipping delete template operation." + ) + + if module.params.get("state") == "modified": + module.fail_json(msg="Module parameter 'modified' not implemented yet!") + + module.exit_json(**result.model_dump(mode="json")) + + +def main(): + run_module() + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/feature_templates_info.py b/plugins/modules/feature_templates_info.py new file mode 100644 index 0000000..23aa483 --- /dev/null +++ b/plugins/modules/feature_templates_info.py @@ -0,0 +1,195 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + + +DOCUMENTATION = r""" +--- +module: feature_templates_info +short_description: Get information about Feature Templates on vManage. +version_added: "0.2.0" +description: + - This module allows you to get and filter Feature Templates from vManage. +options: + filters: + description: + - A dictionary of filters used to select Feature Templates info. + type: dict + required: false + suboptions: + template_type: + description: + - The type of template, eg. "system-vsmart + required: false + default: null + type: str + device_type: + description: + - The device type of the template + required: false + default: null + type: list + elements: str + name: + description: + - The name of the Feature Template. + required: false + default: null + type: str + description: + description: + - Description of the Feature Template. + required: false + default: null + type: str + version: + description: + - Version of the Feature Template. + required: false + default: null + type: str + factory_default: + description: + - If template is Factory Default template. + required: false + default: null + type: bool + template_definiton: + description: + - The definiton of Feature Template. + required: false + default: null + type: str + devices_attached: + description: + - Number of attached devices. + required: false + default: null + type: int + id: + description: + - Feature Template ID. + required: false + default: null + type: str + last_updated_on: + description: + - Last Updated on value. + required: false + default: null + type: int + last_updated_by: + description: + - Last Updated by value. + required: false + default: null + type: str + resource_group: + description: + - Resource Group value. + required: false + default: null + type: str +author: + - Arkadiusz Cichon (acichon@cisco.com) +extends_documentation_fragment: + - cisco.catalystwan.manager_authentication +notes: + - Ensure that the provided credentials have sufficient permissions to manage templates and devices in vManage. +""" + +EXAMPLES = r""" +- name: Get all Non-Default Feature Templates available + cisco.catalystwan.feature_templates_info: + filters: + factory_default: false + manager_credentials: + ... + register: feature_templates +""" + +RETURN = r""" +template_info: + description: A list of dictionaries of templates info + type: list + returned: on success + sample: | + templates_info: + - deviceType: + - vedge-C8000V + devicesAttached: 0 + factoryDefault: false + lastUpdatedBy: example_user + lastUpdatedOn: 111111111 + resourceGroup: example_groupo + templateDefinition: null + templateDescription: AAA Template with both TACACS+ and RADIUS servers + templateId: xxxx-xxxx-xxxx-xxxx + templateMinVersion: X.X.X.X + templateName: example_name + templateType: cedge_aaa +msg: + description: Messages that indicate actions taken or any errors that have occurred. + type: str + returned: always + sample: "Successfully fetched information about template: trial-template" +changed: + description: Indicates whether any change was made. + type: bool + returned: always + sample: false +""" + +from typing import Dict, Optional + +from catalystwan.api.template_api import FeatureTemplate +from catalystwan.models.templates import FeatureTemplateInformation +from catalystwan.typed_list import DataSequence +from pydantic import Field + +from ..module_utils.result import ModuleResult +from ..module_utils.vmanage_module import AnsibleCatalystwanModule + + +class ExtendedModuleResult(ModuleResult): + templates_info: Optional[Dict] = Field(default={}) + + +def run_module(): + module_args = dict( + filters=dict(type="dict", default=None, required=False), + ) + result = ExtendedModuleResult() + + module = AnsibleCatalystwanModule(argument_spec=module_args) + + filters = module.params.get("filters") + + all_templates: DataSequence[FeatureTemplateInformation] = module.get_response_safely( + module.session.api.templates.get, template=FeatureTemplate + ) + + if filters: + filtered_templates = all_templates.filter(**filters) + if filtered_templates: + module.logger.info(f"All Feature Templates filtered with filters: {filters}:\n{filtered_templates}") + result.msg = "Succesfully got all requested Feature Templates Info from vManage" + result.templates_info = [template for template in filtered_templates] + else: + module.logger.warning(msg=f"Feature templates filtered with `{filters}` not present.") + result.msg = f"Feature templates filtered with `{filters}` not present on vManage." + else: + result.msg = "Succesfully got all Feature Templates Info from vManage" + result.templates_info = [template for template in all_templates] + + module.exit_json(**result.model_dump(mode="json")) + + +def main(): + run_module() + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/vmanage_mode.py b/plugins/modules/vmanage_mode.py index e68d7e8..2bda9dd 100644 --- a/plugins/modules/vmanage_mode.py +++ b/plugins/modules/vmanage_mode.py @@ -19,8 +19,8 @@ description: - The state of vManage mode to enforce on the specified devices. type: str - choices: ['present'] - default: 'present' + choices: ["present"] + default: "present" hostnames: description: - A list of hostnames of devices to which the vManage mode will be applied. @@ -67,12 +67,12 @@ returned: always sample: true """ + import traceback from typing import Dict, Literal, Optional, get_args from catalystwan.api.template_api import CLITemplate from catalystwan.session import ManagerHTTPError -from catalystwan.utils.device_model import DeviceModel from catalystwan.utils.personality import Personality from pydantic import Field @@ -111,10 +111,10 @@ def run_module(): for hostname in module.params["hostnames"]: device = devices.filter(hostname=hostname).single_or_default() try: - template_name = f"Default_{hostname}" - device_model = DeviceModel(device.model) + template_name = f"Default-{hostname}" + device_model = device.model if device.personality is Personality.VBOND: - device_model = DeviceModel.VBOND + device_model = "vedge-cloud" cli_template = CLITemplate( template_name=template_name, diff --git a/pyproject.toml b/pyproject.toml index 135f44c..d452061 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,26 +1,22 @@ [tool.poetry] -name = "cisco-catalystwan" -version = "0.1.0" -description = "Ansible modules using vManage-client." +package-mode = false +name = "ansible-collection-cisco-catalystwan" +description = "Ansible modules using catalystwan SDK." authors = ["acichon "] readme = "README.md" [tool.poetry.dependencies] -python = "^3.10.0" -ansible-core = "^2.16.5" +python = "^3.10" +ansible-core = "^2.16.6" ansible = "^9.4.0" -catalystwan = "v0.33.3" -ansible-lint = { version = "^6.9.0", markers = "platform_system != 'Windows'" } - -[tool.poetry.group.dev.dependencies] +catalystwan = "v0.33.8dev7" flake8 = "^5.0.4" -black = "^23.11.0" -pre-commit = "^3.6.2" -ansible-lint = { version = "^6.9.0", markers = "platform_system != 'Windows'" } +black = "^23.12.1" +pre-commit = "3.7" +pydantic = "2.7" +ansible-lint = { version = "6.22.2", markers = "platform_system != 'Windows'" } -[build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" +[tool.poetry.group.dev.dependencies] [tool.black] line-length = 120 diff --git a/requirements.txt b/requirements.txt index 7a29235..d3d7c7c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,66 +1,70 @@ -annotated-types==0.6.0 -ansible==9.4.0 -ansible-compat==4.1.11 -ansible-core==2.16.6 -ansible-lint==6.22.2 -args==0.1.0 -attrs==21.4.0 -black==23.12.1 -bracex==2.4 -catalystwan==0.33.3 -certifi==2024.2.2 -cffi==1.16.0 -cfgv==3.4.0 -charset-normalizer==3.3.2 -ciscoconfparse==1.9.41 -click==8.1.7 -clint==0.5.1 -cryptography==42.0.5 -Deprecated==1.2.14 -distlib==0.3.8 -dnspython==2.6.1 -filelock==3.13.4 -flake8==5.0.4 -flake8-quotes==3.4.0 -hier-config==2.2.3 -identify==2.5.36 -idna==3.7 -Jinja2==3.1.3 -jsonschema==4.17.3 -loguru==0.7.2 -markdown-it-py==3.0.0 -MarkupSafe==2.1.5 -mccabe==0.7.0 -mdurl==0.1.2 -mypy-extensions==1.0.0 -nodeenv==1.8.0 -packaging==23.2 -passlib==1.7.4 -pathspec==0.12.1 -platformdirs==4.2.0 -pre-commit==3.7.0 -pycodestyle==2.9.1 -pycparser==2.22 -pydantic==2.7.0 -pydantic_core==2.18.1 -pyflakes==2.5.0 -Pygments==2.17.2 -pyrsistent==0.20.0 -python-dateutil==2.9.0.post0 -PyYAML==6.0.1 -requests==2.31.0 -requests-toolbelt==1.0.0 -resolvelib==1.0.1 -rich==13.7.1 -ruamel.yaml==0.18.6 -ruamel.yaml.clib==0.2.8 -six==1.16.0 -subprocess-tee==0.4.1 -tenacity==8.2.3 -toml==0.10.2 -typing_extensions==4.11.0 -urllib3==2.2.1 -virtualenv==20.25.3 -wcmatch==8.5.1 -wrapt==1.16.0 -yamllint==1.35.1 +annotated-types==0.6.0 ; python_version >= "3.10" and python_version < "4.0" +ansible-compat==4.1.11 ; python_version >= "3.10" and python_version < "4.0" and platform_system != "Windows" +ansible-core==2.16.6 ; python_version >= "3.10" and python_version < "4.0" +ansible-lint==6.22.2 ; python_version >= "3.10" and python_version < "4.0" and platform_system != "Windows" +ansible==9.4.0 ; python_version >= "3.10" and python_version < "4.0" +args==0.1.0 ; python_version >= "3.10" and python_version < "4.0" +attrs==21.4.0 ; python_version >= "3.10" and python_version < "4.0" +black==23.12.1 ; python_version >= "3.10" and python_version < "4.0" +bracex==2.4 ; python_version >= "3.10" and python_version < "4.0" and platform_system != "Windows" +catalystwan==0.33.6.post0 ; python_version >= "3.10" and python_version < "4.0" +certifi==2024.2.2 ; python_version >= "3.10" and python_version < "4.0" +cffi==1.16.0 ; python_version >= "3.10" and python_version < "4.0" and platform_python_implementation != "PyPy" +cfgv==3.4.0 ; python_version >= "3.10" and python_version < "4.0" +charset-normalizer==3.3.2 ; python_version >= "3.10" and python_version < "4.0" +ciscoconfparse==1.9.41 ; python_version >= "3.10" and python_version < "4.0" +click==8.1.7 ; python_version >= "3.10" and python_version < "4.0" +clint==0.5.1 ; python_version >= "3.10" and python_version < "4.0" +colorama==0.4.6 ; python_version >= "3.10" and python_version < "4.0" and (platform_system == "Windows" or sys_platform == "win32") +cryptography==42.0.5 ; python_version >= "3.10" and python_version < "4.0" +deprecated==1.2.14 ; python_version >= "3.10" and python_version < "4.0" +distlib==0.3.8 ; python_version >= "3.10" and python_version < "4.0" +dnspython==2.6.1 ; python_version >= "3.10" and python_version < "4.0" +filelock==3.13.4 ; python_version >= "3.10" and python_version < "4.0" +flake8-quotes==3.4.0 ; python_version >= "3.10" and python_version < "4.0" +flake8==5.0.4 ; python_version >= "3.10" and python_version < "4.0" +hier-config==2.2.3 ; python_version >= "3.10" and python_version < "4.0" +identify==2.5.36 ; python_version >= "3.10" and python_version < "4.0" +idna==3.7 ; python_version >= "3.10" and python_version < "4.0" +jinja2==3.1.3 ; python_version >= "3.10" and python_version < "4.0" +jsonschema==4.17.3 ; python_version >= "3.10" and python_version < "4.0" and platform_system != "Windows" +loguru==0.7.2 ; python_version >= "3.10" and python_version < "4.0" +markdown-it-py==3.0.0 ; python_version >= "3.10" and python_version < "4.0" and platform_system != "Windows" +markupsafe==2.1.5 ; python_version >= "3.10" and python_version < "4.0" +mccabe==0.7.0 ; python_version >= "3.10" and python_version < "4.0" +mdurl==0.1.2 ; python_version >= "3.10" and python_version < "4.0" and platform_system != "Windows" +mypy-extensions==1.0.0 ; python_version >= "3.10" and python_version < "4.0" +nodeenv==1.8.0 ; python_version >= "3.10" and python_version < "4.0" +packaging==23.2 ; python_version >= "3.10" and python_version < "4.0" +passlib==1.7.4 ; python_version >= "3.10" and python_version < "4.0" +pathspec==0.12.1 ; python_version >= "3.10" and python_version < "4.0" +platformdirs==4.2.0 ; python_version >= "3.10" and python_version < "4.0" +pre-commit==3.7.0 ; python_version >= "3.10" and python_version < "4.0" +pycodestyle==2.9.1 ; python_version >= "3.10" and python_version < "4.0" +pycparser==2.22 ; python_version >= "3.10" and python_version < "4.0" and platform_python_implementation != "PyPy" +pydantic-core==2.18.1 ; python_version >= "3.10" and python_version < "4.0" +pydantic==2.7.0 ; python_version >= "3.10" and python_version < "4.0" +pyflakes==2.5.0 ; python_version >= "3.10" and python_version < "4.0" +pygments==2.17.2 ; python_version >= "3.10" and python_version < "4.0" and platform_system != "Windows" +pyrsistent==0.20.0 ; python_version >= "3.10" and python_version < "4.0" and platform_system != "Windows" +python-dateutil==2.9.0.post0 ; python_version >= "3.10" and python_version < "4.0" +pyyaml==6.0.1 ; python_version >= "3.10" and python_version < "4.0" +requests-toolbelt==1.0.0 ; python_version >= "3.10" and python_version < "4.0" +requests==2.31.0 ; python_version >= "3.10" and python_version < "4.0" +resolvelib==1.0.1 ; python_version >= "3.10" and python_version < "4.0" +rich==13.7.1 ; python_version >= "3.10" and python_version < "4.0" and platform_system != "Windows" +ruamel-yaml-clib==0.2.8 ; platform_python_implementation == "CPython" and python_version < "3.13" and python_version >= "3.10" and platform_system != "Windows" +ruamel-yaml==0.18.6 ; python_version >= "3.10" and python_version < "4.0" and platform_system != "Windows" +setuptools==69.5.1 ; python_version >= "3.10" and python_version < "4.0" +six==1.16.0 ; python_version >= "3.10" and python_version < "4.0" +subprocess-tee==0.4.1 ; python_version >= "3.10" and python_version < "4.0" and platform_system != "Windows" +tenacity==8.2.3 ; python_version >= "3.10" and python_version < "4.0" +toml==0.10.2 ; python_version >= "3.10" and python_version < "4.0" +tomli==2.0.1 ; python_version >= "3.10" and python_version < "3.11" +typing-extensions==4.11.0 ; python_version >= "3.10" and python_version < "4.0" +urllib3==2.2.1 ; python_version >= "3.10" and python_version < "4.0" +virtualenv==20.25.3 ; python_version >= "3.10" and python_version < "4.0" +wcmatch==8.5.1 ; python_version >= "3.10" and python_version < "4.0" and platform_system != "Windows" +win32-setctime==1.1.0 ; python_version >= "3.10" and python_version < "4.0" and sys_platform == "win32" +wrapt==1.16.0 ; python_version >= "3.10" and python_version < "4.0" +yamllint==1.35.1 ; python_version >= "3.10" and python_version < "4.0" and platform_system != "Windows" diff --git a/utils/docs_fragments_template.j2 b/utils/docs_fragments_template.j2 new file mode 100644 index 0000000..c9167c4 --- /dev/null +++ b/utils/docs_fragments_template.j2 @@ -0,0 +1,16 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r''' +{{ yaml_data | to_nice_yaml | trim }} + ''' diff --git a/utils/ft_device_model.j2 b/utils/ft_device_model.j2 new file mode 100644 index 0000000..4a6567a --- /dev/null +++ b/utils/ft_device_model.j2 @@ -0,0 +1,26 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# This file is autogenerated by `utils/feature_template_docs_generator.py` + + +from __future__ import annotations + + +class ModuleDocFragment(object): + DOCUMENTATION = r''' +options: + device_models: + description: + - Defines the SD-WAN device type for template application. + type: list + default: [] + elements: str + choices: +{% for model in device_models %} + - "{{ model }}" +{% endfor %} + ''' diff --git a/utils/ft_generator.py b/utils/ft_generator.py new file mode 100644 index 0000000..c537dbd --- /dev/null +++ b/utils/ft_generator.py @@ -0,0 +1,307 @@ +# Copyright 2024 Cisco Systems, Inc. and its affiliates +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import annotations + +from enum import Enum +from pathlib import Path, PurePath +from pprint import pformat +from typing import Annotated, Literal, Type, Union, get_args, get_origin + +import yaml +from catalystwan.api.templates.device_variable import DeviceVariable +from catalystwan.api.templates.models.supported import available_models +from catalystwan.models.common import DeviceModel +from jinja2 import Environment, FileSystemLoader +from pydantic import BaseModel +from pydantic.fields import FieldInfo + +PROJECT_ROOT_DIR = PurePath(Path.cwd()) + + +def safe_issubclass(type_, class_): + try: + return issubclass(type_, class_) + except TypeError: + return False + + +def is_pydantic_model(type_): + try: + return issubclass(type_, BaseModel) + except TypeError: + return False + + +def field_to_ansible_option(field: FieldInfo, field_name: str, model_name: str): + option = { + "description": [field.description], + "required": field.is_required(), + "default": None, + "type": None, # "str", #None, # default type is None, will be overwritten as needed + } + if not field.is_required(): + if safe_issubclass(field.default, str) or safe_issubclass(field.default, str): + option["default"] = field.default + elif safe_issubclass(type(field.default), Enum): + option["default"] = field.default.value + elif safe_issubclass(type(field.default), str): + option["default"] = field.default + elif safe_issubclass(type(field.default), list): + option["default"] = field.default + elif type(field.default) is DeviceVariable: + option["default"] = field.default.name + + field_type = get_origin(field.annotation) or field.annotation + args = get_args(field.annotation) + subargs_base_types = [get_origin(annotation) for annotation in args] + + if field_type == bool: + option["type"] = "bool" + + elif field_type == int: + option["type"] = "int" + + elif field_type == DeviceVariable: + option["type"] = "raw" + option["suboptions"] = { + "name": { + "default": option["default"], + "required": True, + "type": "str", + "description": "Device Specific Variables name", + } + } + del option["default"] + + elif field_type == Union and DeviceVariable in args: + option["type"] = "raw" + option["suboptions"] = { + "name": { + "default": option["default"], + "required": True, + "type": "str", + "description": "Device Specific Variables name", + } + } + del option["default"] + + elif is_pydantic_model(field_type): + option["type"] = "dict" + option["suboptions"] = model_to_ansible_options(field_type, model_name) + + elif field_type == list or (field_type == Union and list in subargs_base_types): + elements_type = next((arg for arg in args if arg is not None), None) + if is_pydantic_model(elements_type): + option["type"] = "list" + option["elements"] = "dict" + option["suboptions"] = model_to_ansible_options(elements_type, model_name) + else: + origin_type = get_origin(elements_type) + if origin_type == list: + user_class = get_args(elements_type)[0] + else: + user_class = None + if is_pydantic_model(user_class): + option["type"] = "list" + option["elements"] = "dict" + option["suboptions"] = model_to_ansible_options(user_class, model_name) + elif safe_issubclass(user_class, Enum): + option["type"] = "list" + option["elements"] = "str" + option["choices"] = [item.value for item in user_class] + elif get_origin(user_class) == Literal: + option["type"] = "list" + option["elements"] = "str" + option["choices"] = [item for item in get_args(user_class)] + elif origin_type == Literal: + option["type"] = "list" + option["elements"] = "str" + option["choices"] = [item for item in get_args(elements_type)] + elif user_class == int: + option["type"] = "list" + option["elements"] = "int" + else: + option["type"] = "list" + option["elements"] = "str" + + elif safe_issubclass(field_type, Enum): + option["type"] = "str" + option["choices"] = [item.value for item in field_type] + + # Special for field.description == "The interface configuration for the IPv4 static route." + elif field_type == Union and is_pydantic_model(next((arg for arg in args if arg is not None), None)): + elements_type = next((arg for arg in args if arg is not None), None) + option["type"] = "dict" + option["elements"] = "dict" + option["suboptions"] = model_to_ansible_options(elements_type, model_name) + + elif field_type == Union and safe_issubclass(next((arg for arg in args if arg is not None), None), Enum): + option["type"] = "str" + option["choices"] = [item.value for item in args[0]] + + elif field_type == Union and bool in args: + option["type"] = "bool" + + elif field_type == Union and int in args: + option["type"] = "int" + + elif field_type == Union and Annotated in subargs_base_types: + elements_type = next((arg for arg in args if arg is not None), None) + origin_type = get_origin(elements_type) + if origin_type == Annotated: + user_class = get_args(elements_type)[0] + else: + user_class = None + if user_class == bool: + option["type"] = "bool" + option["default"] = field.default + + # THIS LINE IS NEWEST FOR LITERALS + elif field_type == Union and Literal in subargs_base_types: + elements_type = next((arg for arg in args if arg is not None), None) + option["type"] = "str" + option["choices"] = [item for item in get_args(elements_type)] + + elif field_type == Literal: + option["type"] = "str" + option["choices"] = [item for item in args] + + else: + option["type"] = "str" + if hasattr(field.default, "value"): + option["default"] = field.default.value + + return option + + +def model_to_ansible_options(model: Type[BaseModel], model_name: str): + options = {} + for field_name, field in model.model_fields.items(): + if field_name in [ + "template_name", + "template_description", + "device_models", + "device_specific_variables", + ]: + continue + options[field_name] = field_to_ansible_option(field, field_name, model_name) + return options + + +def generate_ansible_docs(model: Type[BaseModel], model_name: str): + if not hasattr(model, "_docs_description"): + raise ValueError(f"Missing '_docs_description' documentation field for model {model_name}!") + ansible_docs = { + "options": { + model_name: { + "description": model._docs_description.default, + "type": "dict", + "suboptions": model_to_ansible_options(model, model_name), + } + } + } + return ansible_docs + + +# Function to parse YAML data and return the argument spec +def generate_arg_spec(yaml_data): + # Load the YAML data + data = yaml.safe_load(yaml_data) + + # Function to recursively parse the options + def parse_options(options): + arg_spec = {} + for opt_name, opt_info in options.items(): + if "type" in opt_info: + arg_spec[opt_name] = { + "type": opt_info["type"], + "required": opt_info.get("required", False), + "default": opt_info.get("default", None), + } + + # Special case for 'list' type + if opt_info["type"] == "list" and "elements" in opt_info: + arg_spec[opt_name]["elements"] = opt_info["elements"] + + # Recursively handle suboptions if present + if "suboptions" in opt_info: + arg_spec[opt_name]["options"] = parse_options(opt_info["suboptions"]) + + return arg_spec + + # Get the top-level options and parse them + options = data.get("options", {}) + return parse_options(options) + + +for model_name, model_module in available_models.items(): + # Part for Ansible documentation + ansible_docs = generate_ansible_docs(model_module, model_name) + + def to_nice_yaml(data): + return yaml.dump(data, allow_unicode=True, default_flow_style=False, indent=4, sort_keys=False) + + template_dir = PROJECT_ROOT_DIR / "utils" + env = Environment( + loader=FileSystemLoader(template_dir), trim_blocks=True, lstrip_blocks=True, keep_trailing_newline=True + ) + env.filters["to_nice_yaml"] = to_nice_yaml + + template_file = PurePath("docs_fragments_template.j2") + template = env.get_template(str(template_file)) + try: + output = template.render(yaml_data=ansible_docs) + except Exception as ex: + print(ex) + print(ansible_docs) + raise ex + + filename = f"{PROJECT_ROOT_DIR}/plugins/doc_fragments/feature_template_{model_name}.py" + with open(filename, "w") as f: + f.write(output) + + print(f"File '{filename}' has been written successfully.") + + # Part for Ansible module arguments specification + yaml_str = yaml.dump(ansible_docs, sort_keys=False) + + # Generate the argument spec + arg_spec = generate_arg_spec(yaml_str) + + # Define the variable name + variable_name = f"{model_name}_definition" + + # Write the generated dictionary to a Python file + output_file = f"{PROJECT_ROOT_DIR}/plugins/module_utils/feature_templates/{model_name}.py" + with open(output_file, "w") as file: + file.write(f"{variable_name} = ") + # Use pformat to get a string representation of the dictionary + file.write(pformat(arg_spec, indent=2, width=80)) + file.write("\n") + print(f"File '{output_file}' has been written successfully.") + + # Part for Ansible DeviceModel docs fragment + # Load the template file + template_file = "ft_device_model.j2" + template = env.get_template(template_file) + + # Render the template with the DeviceModel enum + output = template.render(device_models=get_args(DeviceModel)) + + # Write the output to a file + file_name = f"{PROJECT_ROOT_DIR}/plugins/doc_fragments/device_models_feature_template.py" + with open(file_name, "w") as f: + f.write(output) + print(f"File '{file_name}' has been written successfully.") + + +print( + """ + When used, note that Device Specific Variables doesn't have description and it required manual effort to fix + these in documentation. Example: cisco.catalystwan.feature_template_cisco_system requires updating few fields. + Look for '- null' fields. + That will be solved once we will have Device Specific Variables in SDK properly defined. + + """ +)