OS9 Ansible Collections (#2)
* adding OS9 ansible collections * adding OS9 collections Co-authored-by: Patil <Komal_uttamrao_Patil@Dell.com>
This commit is contained in:
parent
0f46de1d20
commit
90b090b021
344 changed files with 16464 additions and 1408 deletions
201
LICENSE
Normal file
201
LICENSE
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright (c) 2020, Dell Inc. All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
54
README.md
54
README.md
|
@ -1,4 +1,52 @@
|
||||||
[](https://github.com/ansible-collection-migration/dellemc_networking.os9/actions?query=workflow%3A%22Collection%20test%20suite%22)
|
# Ansible Network Collection for Dell EMC OS9
|
||||||
|
|
||||||
Ansible Collection: dellemc_networking.os9
|
## Collection contents
|
||||||
=================================================
|
The OS9 Ansible Network Collection includes the Ansible modules, plugins and roles required to work on a Dell EMC OS9 PowerSwitch. It also includes sample playbooks and documents that illustrate how the collection can be used.
|
||||||
|
|
||||||
|
### Ansible modules
|
||||||
|
The following Ansible modules are part of the OS9 collection:
|
||||||
|
|
||||||
|
- **os9_command.py** — Run commands on remote devices running Dell EMC OS9
|
||||||
|
|
||||||
|
- **os9_config.py** — Manage configuration sections on remote devices running Dell EMC OS9
|
||||||
|
|
||||||
|
- **os9_facts.py** — Collect facts from remote devices running Dell EMC OS9
|
||||||
|
|
||||||
|
### Ansible roles
|
||||||
|
The roles facilitate provisioning of device running Dell EMC OS9. Some of the roles included in the collection are os9_aaa , os9_bgp, os9_ecmp, and so on. The docs directory in the collection includes documentation for each of the roles part of the collection.
|
||||||
|
|
||||||
|
### Playbooks
|
||||||
|
The playbooks directory includes sample playbooks that illustrate the usage of OS9 collections for provisioning device running Dell EMC OS9.
|
||||||
|
|
||||||
|
## Collection Installation
|
||||||
|
Install the latest version of OS9 collection from Ansible Galaxy:
|
||||||
|
|
||||||
|
ansible-galaxy collection install dellemc.os9
|
||||||
|
|
||||||
|
To install a specific version, a version range identifier must be specified. For example, to install the most recent version that is greater than or equal to 1.0.0 and less than 2.0.0:
|
||||||
|
|
||||||
|
ansible-galaxy collection install 'dellemc.os10:>=1.0.0,<2.0.0'
|
||||||
|
|
||||||
|
## Sample playbook
|
||||||
|
|
||||||
|
- hosts: os9_sw1
|
||||||
|
connection: network_cli
|
||||||
|
collections:
|
||||||
|
- dellemc.os9
|
||||||
|
roles:
|
||||||
|
- os9_vlan
|
||||||
|
|
||||||
|
> **NOTE**: The environment variable ANSIBLE_NETWORK_GROUP_MODULES should be set to 'os9' for using os9-collections in the playbook.
|
||||||
|
|
||||||
|
## Sample host_vars/os9_sw1.yaml
|
||||||
|
|
||||||
|
hostname: os9_sw1
|
||||||
|
# parameters for connection type network_cli
|
||||||
|
ansible_ssh_user: xxxx
|
||||||
|
ansible_ssh_pass: xxxx
|
||||||
|
ansible_network_os: dellemc.os9.os9
|
||||||
|
|
||||||
|
## Sample inventory.yaml
|
||||||
|
|
||||||
|
[os9]
|
||||||
|
os9_sw1 ansible_host=100.104.28.119
|
||||||
|
|
0
docs/os9_ecmp.md
Normal file
0
docs/os9_ecmp.md
Normal file
0
docs/os9_interface.md
Normal file
0
docs/os9_interface.md
Normal file
0
docs/os9_lag.md
Normal file
0
docs/os9_lag.md
Normal file
0
docs/os9_lldp.md
Normal file
0
docs/os9_lldp.md
Normal file
0
docs/os9_logging.md
Normal file
0
docs/os9_logging.md
Normal file
0
docs/os9_ntp.md
Normal file
0
docs/os9_ntp.md
Normal file
0
docs/os9_prefix_list.md
Normal file
0
docs/os9_prefix_list.md
Normal file
0
docs/os9_sflow.md
Normal file
0
docs/os9_sflow.md
Normal file
0
docs/os9_snmp.md
Normal file
0
docs/os9_snmp.md
Normal file
0
docs/os9_system.md
Normal file
0
docs/os9_system.md
Normal file
0
docs/os9_users.md
Normal file
0
docs/os9_users.md
Normal file
0
docs/os9_vlan.md
Normal file
0
docs/os9_vlan.md
Normal file
0
docs/os9_vlt.md
Normal file
0
docs/os9_vlt.md
Normal file
0
docs/os9_vrf.md
Normal file
0
docs/os9_vrf.md
Normal file
0
docs/os9_vrrp.md
Normal file
0
docs/os9_vrrp.md
Normal file
0
docs/os9_xstp.md
Normal file
0
docs/os9_xstp.md
Normal file
26
galaxy.yml
26
galaxy.yml
|
@ -1,16 +1,16 @@
|
||||||
namespace: dellemc_networking
|
|
||||||
name: os9
|
|
||||||
version: 0.1.0
|
|
||||||
readme: README.md
|
|
||||||
authors:
|
authors:
|
||||||
- Abirami N (github.com/abirami-n)
|
- Senthil Ganesan Ganesan <Senthil_Kumar_Ganesa@Dell.com>
|
||||||
description: null
|
- Komal Patil <Komal_uttamrao_Patil@dell.com>
|
||||||
license: GPL-3.0-or-later
|
|
||||||
license_file: COPYING
|
|
||||||
tags: null
|
|
||||||
dependencies:
|
dependencies:
|
||||||
ansible.netcommon: '>=0.0.1'
|
ansible.netcommon: '>=0.0.1'
|
||||||
repository: https://github.com:ansible-collections/dellemc_networking.os9.git
|
description: Ansible Network Collections for Dell EMC OS9
|
||||||
documentation: https://github.com/ansible-collections/dellemc_networking.os9/tree/master/docs
|
license_file: LICENSE
|
||||||
homepage: https://github.com:ansible-collections/dellemc_networking.os9
|
name: os9
|
||||||
issues: https://github.com:ansible-collections/dellemc_networking.os9
|
namespace: dellemc
|
||||||
|
readme: README.md
|
||||||
|
tags: [dell, dellemc, os9, emc, networking]
|
||||||
|
version: 1.0.2
|
||||||
|
repository: 'https://github.com:ansible-collections/dellemc.os9'
|
||||||
|
documentation: 'https://github.com/ansible-collections/dellemc.os9/tree/master/docs'
|
||||||
|
homepage: 'https://github.com:ansible-collections/dellemc.os9'
|
||||||
|
issues: 'https://github.com:ansible-collections/dellemc.os9/issues'
|
||||||
|
|
35
playbooks/README.md
Normal file
35
playbooks/README.md
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
# Provision CLOS fabric using the Ansible collection for Dell EMC OS9
|
||||||
|
|
||||||
|
This example describes how to use Ansible to build a CLOS fabric with Dell EMC OS9 switches. The sample topology is a two-tier CLOS fabric with two spines and four leaves connected as mesh. eBGP is running between the two tiers. All switches in spine have the same AS number, and each leaf switch has a unique AS number. All AS numbers used are private.
|
||||||
|
|
||||||
|
For application load-balancing purposes, the same prefix is advertised from multiple leaf switches and uses _BGP multipath relax_ feature.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Create a simple Ansible playbook
|
||||||
|
|
||||||
|
**Step 1**
|
||||||
|
Create an inventory file called `inventory.yaml`, then specify the device IP address.
|
||||||
|
|
||||||
|
**Step 2**
|
||||||
|
Create a group variable file called `group_vars/all`, then define credentials and SNMP variables.
|
||||||
|
|
||||||
|
**Step 3**
|
||||||
|
Create a group variable file called `group_vars/spine.yaml`, then define credentials, hostname, and BGP neighbors of spine group.
|
||||||
|
|
||||||
|
**Step 4**
|
||||||
|
Create a host variable file called `host_vars/spine1.yaml`, then define the host, credentials, and transport.
|
||||||
|
Create a host variable file called `host_vars/spine2.yaml`, then define the host, credentials, and transport.
|
||||||
|
|
||||||
|
Create a host variable file called `host_vars/leaf1.yaml`, then define the host, credentials, and transport.
|
||||||
|
Create a host variable file called `host_vars/leaf2.yaml`, then define the host, credentials, and transport.
|
||||||
|
Create a host variable file called `host_vars/leaf3.yaml`, then define the host, credentials, and transport.
|
||||||
|
Create a host variable file called `host_vars/leaf4.yaml`, then define the host, credentials, and transport.
|
||||||
|
|
||||||
|
**Step 5**
|
||||||
|
Create a playbook called `datacenter.yaml`.
|
||||||
|
|
||||||
|
**Step 6**
|
||||||
|
Run the playbook.
|
||||||
|
|
||||||
|
`ansible-playbook -i inventory.yaml datacenter.yaml`
|
11
playbooks/datacenter.yaml
Normal file
11
playbooks/datacenter.yaml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
- hosts: datacenter
|
||||||
|
gather_facts: no
|
||||||
|
connection: network_cli
|
||||||
|
collections:
|
||||||
|
- dellemc.os9
|
||||||
|
roles:
|
||||||
|
- os9_interface
|
||||||
|
- os9_bgp
|
||||||
|
- os9_snmp
|
||||||
|
- os9_system
|
10
playbooks/group_vars/all
Normal file
10
playbooks/group_vars/all
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
ansible_ssh_user: xxxxx
|
||||||
|
ansible_ssh_pass: xxxxx
|
||||||
|
ansible_network_os: dellemc.os9.os9
|
||||||
|
build_dir: ../tmp/tmp_os9
|
||||||
|
|
||||||
|
os9_snmp:
|
||||||
|
snmp_community:
|
||||||
|
- name: public
|
||||||
|
access_mode: ro
|
||||||
|
state: present
|
64
playbooks/group_vars/spine.yaml
Normal file
64
playbooks/group_vars/spine.yaml
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
ansible_ssh_user: xxxxx
|
||||||
|
ansible_ssh_pass: xxxxx
|
||||||
|
ansible_network_os: dellemc.os9.os9
|
||||||
|
|
||||||
|
os9_system:
|
||||||
|
hostname: "{{ spine_hostname }}"
|
||||||
|
|
||||||
|
os9_bgp:
|
||||||
|
asn: 64901
|
||||||
|
router_id: "{{ bgp_router_id }}"
|
||||||
|
best_path:
|
||||||
|
as_path: ignore
|
||||||
|
as_path_state: present
|
||||||
|
med:
|
||||||
|
- attribute: confed
|
||||||
|
state: present
|
||||||
|
neighbor:
|
||||||
|
- type: ipv4
|
||||||
|
remote_asn: "{{ bgp_neigh1_remote_asn }}"
|
||||||
|
ip: "{{ bgp_neigh1_ip }}"
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv4
|
||||||
|
remote_asn: "{{ bgp_neigh2_remote_asn }}"
|
||||||
|
ip: "{{ bgp_neigh2_ip }}"
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv4
|
||||||
|
remote_asn: "{{ bgp_neigh3_remote_asn }}"
|
||||||
|
ip: "{{ bgp_neigh3_ip }}"
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv4
|
||||||
|
remote_asn: "{{ bgp_neigh4_remote_asn }}"
|
||||||
|
ip: "{{ bgp_neigh4_ip }}"
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv6
|
||||||
|
remote_asn: "{{ bgp_neigh5_remote_asn }}"
|
||||||
|
ip: "{{ bgp_neigh5_ip }}"
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv6
|
||||||
|
remote_asn: "{{ bgp_neigh6_remote_asn }}"
|
||||||
|
ip: "{{ bgp_neigh6_ip }}"
|
||||||
|
admin: up
|
||||||
|
address_family:
|
||||||
|
- type: ipv4
|
||||||
|
activate: false
|
||||||
|
state: present
|
||||||
|
- type: ipv6
|
||||||
|
activate: true
|
||||||
|
state: present
|
||||||
|
state: present
|
||||||
|
- type: ipv6
|
||||||
|
remote_asn: "{{ bgp_neigh7_remote_asn }}"
|
||||||
|
ip: "{{ bgp_neigh7_ip }}"
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv6
|
||||||
|
remote_asn: "{{ bgp_neigh8_remote_asn }}"
|
||||||
|
ip: "{{ bgp_neigh8_ip }}"
|
||||||
|
admin: up
|
||||||
|
state: present
|
61
playbooks/host_vars/leaf1.yaml
Normal file
61
playbooks/host_vars/leaf1.yaml
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
ansible_ssh_user: xxxxx
|
||||||
|
ansible_ssh_pass: xxxxx
|
||||||
|
ansible_network_os: dellemc.os9.os9
|
||||||
|
leaf_hostname: "leaf-1"
|
||||||
|
os9_system:
|
||||||
|
hostname: "{{ leaf_hostname }}"
|
||||||
|
hash_algo:
|
||||||
|
algo:
|
||||||
|
- name: ecmp
|
||||||
|
mode: xor1
|
||||||
|
state: present
|
||||||
|
os9_interface:
|
||||||
|
TenGigabitEthernet 0/0:
|
||||||
|
desc: "Connected to Spine 1"
|
||||||
|
mtu: 9216
|
||||||
|
portmode:
|
||||||
|
admin: up
|
||||||
|
switchport: False
|
||||||
|
ip_and_mask: 100.1.1.2/24
|
||||||
|
ipv6_and_mask: 2001:100:1:1::2/64
|
||||||
|
state_ipv6: present
|
||||||
|
TenGigabitEthernet 0/1:
|
||||||
|
desc: "Connected to Spine 2"
|
||||||
|
mtu: 9216
|
||||||
|
portmode:
|
||||||
|
admin: up
|
||||||
|
switchport: False
|
||||||
|
ip_and_mask: 100.2.1.2/24
|
||||||
|
ipv6_and_mask: 2001:100:2:1::2/64
|
||||||
|
state_ipv6: present
|
||||||
|
os9_bgp:
|
||||||
|
asn: 64801
|
||||||
|
router_id: 100.0.2.1
|
||||||
|
best_path:
|
||||||
|
as_path: ignore
|
||||||
|
as_path_state: present
|
||||||
|
med:
|
||||||
|
- attribute: confed
|
||||||
|
state: present
|
||||||
|
neighbor:
|
||||||
|
- type: ipv4
|
||||||
|
remote_asn: 64901
|
||||||
|
ip: 100.1.1.1
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv4
|
||||||
|
remote_asn: 64901
|
||||||
|
ip: 100.2.1.1
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv6
|
||||||
|
remote_asn: 64901
|
||||||
|
ip: 2001:100:1:1::1
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv6
|
||||||
|
remote_asn: 64901
|
||||||
|
ip: 2001:100:2:1::1
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
state: present
|
65
playbooks/host_vars/leaf2.yaml
Normal file
65
playbooks/host_vars/leaf2.yaml
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
hostname: leaf2
|
||||||
|
ansible_ssh_user: xxxxx
|
||||||
|
ansible_ssh_pass: xxxxx
|
||||||
|
ansible_network_os: dellemc.os9.os9
|
||||||
|
leaf_hostname: "leaf-2"
|
||||||
|
os9_system:
|
||||||
|
hostname: "{{ leaf_hostname }}"
|
||||||
|
hash_algo:
|
||||||
|
algo:
|
||||||
|
- name: ecmp
|
||||||
|
mode: xor1
|
||||||
|
state: present
|
||||||
|
os9_interface:
|
||||||
|
TenGigabitEthernet 0/0:
|
||||||
|
desc: "Connected to Spine 1"
|
||||||
|
mtu: 9216
|
||||||
|
portmode:
|
||||||
|
admin: up
|
||||||
|
switchport: False
|
||||||
|
ip_and_mask: 100.1.17.2/24
|
||||||
|
ipv6_and_mask: 2001:100:1:11::2/64
|
||||||
|
state_ipv6: present
|
||||||
|
TenGigabitEthernet 0/1:
|
||||||
|
desc: "Connected to Spine 2"
|
||||||
|
mtu: 9216
|
||||||
|
portmode:
|
||||||
|
admin: up
|
||||||
|
switchport: False
|
||||||
|
ip_and_mask: 100.2.17.2/24
|
||||||
|
ipv6_and_mask: 2001:100:2:11::2/64
|
||||||
|
os9_bgp:
|
||||||
|
asn: 64802
|
||||||
|
router_id: 100.0.2.2
|
||||||
|
best_path:
|
||||||
|
as_path: ignore
|
||||||
|
as_path_state: present
|
||||||
|
med:
|
||||||
|
- attribute: confed
|
||||||
|
state: present
|
||||||
|
neighbor:
|
||||||
|
- type: ipv4
|
||||||
|
remote_asn: 64901
|
||||||
|
ip: 100.1.18.1
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv4
|
||||||
|
remote_asn: 64901
|
||||||
|
ip: 100.1.17.1
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv4
|
||||||
|
remote_asn: 64901
|
||||||
|
ip: 100.2.17.1
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv6
|
||||||
|
remote_asn: 64901
|
||||||
|
ip: 2001:100:1:11::1
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv6
|
||||||
|
remote_asn: 64901
|
||||||
|
ip: 2001:100:2:11::1
|
||||||
|
admin: up
|
||||||
|
state: present
|
65
playbooks/host_vars/leaf3.yaml
Normal file
65
playbooks/host_vars/leaf3.yaml
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
hostname: leaf3
|
||||||
|
ansible_ssh_user: xxxxx
|
||||||
|
ansible_ssh_pass: xxxxx
|
||||||
|
ansible_network_os: dellemc.os9.os9
|
||||||
|
leaf_hostname: "leaf-3"
|
||||||
|
os9_system:
|
||||||
|
hostname: "{{ leaf_hostname }}"
|
||||||
|
hash_algo:
|
||||||
|
algo:
|
||||||
|
- name: ecmp
|
||||||
|
mode: xor1
|
||||||
|
state: present
|
||||||
|
os9_interface:
|
||||||
|
TenGigabitEthernet 0/0:
|
||||||
|
desc: "Connected to Spine 1"
|
||||||
|
mtu: 9216
|
||||||
|
portmode:
|
||||||
|
admin: up
|
||||||
|
switchport: False
|
||||||
|
ip_and_mask: 100.1.33.2/24
|
||||||
|
ipv6_and_mask: 2001:100:1:21::2/64
|
||||||
|
state_ipv6: present
|
||||||
|
TenGigabitEthernet 0/1:
|
||||||
|
desc: "Connected to Spine 2"
|
||||||
|
mtu: 9216
|
||||||
|
portmode:
|
||||||
|
admin: up
|
||||||
|
switchport: False
|
||||||
|
ip_and_mask: 100.2.33.2/24
|
||||||
|
ipv6_and_mask: 2001:100:2:21::2/64
|
||||||
|
os9_bgp:
|
||||||
|
asn: 64803
|
||||||
|
router_id: 100.0.2.3
|
||||||
|
best_path:
|
||||||
|
as_path: ignore
|
||||||
|
as_path_state: present
|
||||||
|
med:
|
||||||
|
- attribute: confed
|
||||||
|
state: present
|
||||||
|
neighbor:
|
||||||
|
- type: ipv4
|
||||||
|
remote_asn: 64901
|
||||||
|
ip: 100.1.33.1
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv4
|
||||||
|
remote_asn: 64901
|
||||||
|
ip: 100.2.33.1
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv6
|
||||||
|
remote_asn: 64901
|
||||||
|
ip: 2001:100:1:21::1
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv6
|
||||||
|
remote_asn: 64901
|
||||||
|
ip: 2001:100:1:22::1
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv6
|
||||||
|
remote_asn: 64901
|
||||||
|
ip: 2001:100:2:21::1
|
||||||
|
admin: up
|
||||||
|
state: present
|
61
playbooks/host_vars/leaf4.yaml
Normal file
61
playbooks/host_vars/leaf4.yaml
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
hostname: leaf4
|
||||||
|
ansible_ssh_user: xxxxx
|
||||||
|
ansible_ssh_pass: xxxxx
|
||||||
|
ansible_network_os: dellemc.os9.os9
|
||||||
|
leaf_hostname: "leaf-4"
|
||||||
|
os9_system:
|
||||||
|
hostname: "{{ leaf_hostname }}"
|
||||||
|
hash_algo:
|
||||||
|
algo:
|
||||||
|
- name: ecmp
|
||||||
|
mode: xor1
|
||||||
|
state: present
|
||||||
|
os9_interface:
|
||||||
|
TenGigabitEthernet 0/0:
|
||||||
|
desc: "Connected to Spine 1"
|
||||||
|
mtu: 9216
|
||||||
|
portmode:
|
||||||
|
admin: up
|
||||||
|
switchport: False
|
||||||
|
ip_and_mask: 100.1.49.2/24
|
||||||
|
ipv6_and_mask: 2001:100:1:31::2/64
|
||||||
|
state_ipv6: present
|
||||||
|
TenGigabitEthernet 0/1:
|
||||||
|
desc: "Connected to Spine 2"
|
||||||
|
mtu: 9216
|
||||||
|
portmode:
|
||||||
|
admin: up
|
||||||
|
switchport: False
|
||||||
|
ip_and_mask: 100.2.49.2/24
|
||||||
|
ipv6_and_mask: 2001:100:2:31::2/64
|
||||||
|
state_ipv6: present
|
||||||
|
os9_bgp:
|
||||||
|
asn: 64804
|
||||||
|
router_id: 100.0.2.4
|
||||||
|
best_path:
|
||||||
|
as_path: ignore
|
||||||
|
as_path_state: present
|
||||||
|
med:
|
||||||
|
- attribute: confed
|
||||||
|
state: present
|
||||||
|
neighbor:
|
||||||
|
- type: ipv4
|
||||||
|
remote_asn: 64901
|
||||||
|
ip: 100.1.49.1
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv4
|
||||||
|
remote_asn: 64901
|
||||||
|
ip: 100.2.49.1
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv6
|
||||||
|
remote_asn: 64901
|
||||||
|
ip: 2001:100:1:31::1
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- type: ipv6
|
||||||
|
remote_asn: 64901
|
||||||
|
ip: 2001:100:2:31::1
|
||||||
|
admin: up
|
||||||
|
state: present
|
61
playbooks/host_vars/spine1.yaml
Normal file
61
playbooks/host_vars/spine1.yaml
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
hostname: spine1
|
||||||
|
ansible_ssh_user: xxxxx
|
||||||
|
ansible_ssh_pass: xxxxx
|
||||||
|
ansible_network_os: dellemc.os9.os9
|
||||||
|
spine_hostname: "spine-1"
|
||||||
|
|
||||||
|
os9_interface:
|
||||||
|
TenGigabitEthernet 0/2:
|
||||||
|
desc: "Connected to leaf 1"
|
||||||
|
mtu: 9216
|
||||||
|
portmode:
|
||||||
|
admin: up
|
||||||
|
switchport: False
|
||||||
|
ip_and_mask: 100.1.1.1/24
|
||||||
|
ipv6_and_mask: 2001:100:1:1::1/64
|
||||||
|
state_ipv6: present
|
||||||
|
TenGigabitEthernet 0/3:
|
||||||
|
desc: "Connected to leaf 2"
|
||||||
|
mtu: 9216
|
||||||
|
portmode:
|
||||||
|
admin: up
|
||||||
|
switchport: False
|
||||||
|
ip_and_mask: 100.1.33.1/24
|
||||||
|
ipv6_and_mask: 2001:100:1:21::1/64
|
||||||
|
state_ipv6: present
|
||||||
|
TenGigabitEthernet 0/4:
|
||||||
|
desc: "Connected to leaf 3"
|
||||||
|
mtu: 9216
|
||||||
|
portmode:
|
||||||
|
admin: up
|
||||||
|
switchport: False
|
||||||
|
ip_and_mask: 100.1.17.1/24
|
||||||
|
ipv6_and_mask: 2001:100:1:11::1/64
|
||||||
|
state_ipv6: present
|
||||||
|
TenGigabitEthernet 0/5:
|
||||||
|
desc: "Connected to leaf 4"
|
||||||
|
mtu: 9216
|
||||||
|
portmode:
|
||||||
|
admin: up
|
||||||
|
switchport: False
|
||||||
|
ip_and_mask: 100.1.49.1/24
|
||||||
|
ipv6_and_mask: 2001:100:1:31::1/64
|
||||||
|
state_ipv6: present
|
||||||
|
|
||||||
|
bgp_router_id: "100.0.1.1"
|
||||||
|
bgp_neigh1_remote_asn: 64801
|
||||||
|
bgp_neigh1_ip: "100.1.1.2"
|
||||||
|
bgp_neigh2_remote_asn: 64803
|
||||||
|
bgp_neigh2_ip: "100.1.33.2"
|
||||||
|
bgp_neigh3_remote_asn: 64802
|
||||||
|
bgp_neigh3_ip: "100.1.17.2"
|
||||||
|
bgp_neigh4_remote_asn: 64804
|
||||||
|
bgp_neigh4_ip: "100.1.49.2"
|
||||||
|
bgp_neigh5_remote_asn: 64801
|
||||||
|
bgp_neigh5_ip: "2001:100:1:1::2"
|
||||||
|
bgp_neigh6_remote_asn: 64802
|
||||||
|
bgp_neigh6_ip: "2001:100:1:11::2"
|
||||||
|
bgp_neigh7_remote_asn: 64803
|
||||||
|
bgp_neigh7_ip: "2001:100:1:21::2"
|
||||||
|
bgp_neigh8_remote_asn: 64804
|
||||||
|
bgp_neigh8_ip: "2001:100:1:31::2"
|
60
playbooks/host_vars/spine2.yaml
Normal file
60
playbooks/host_vars/spine2.yaml
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
hostname: spine2
|
||||||
|
ansible_ssh_user: xxxxx
|
||||||
|
ansible_ssh_pass: xxxxx
|
||||||
|
ansible_network_os: dellemc.os9.os9
|
||||||
|
spine_hostname: "spine-2"
|
||||||
|
os9_interface:
|
||||||
|
TenGigabitEthernet 0/6:
|
||||||
|
desc: "Connected to leaf 1"
|
||||||
|
mtu: 9216
|
||||||
|
portmode:
|
||||||
|
admin: up
|
||||||
|
switchport: False
|
||||||
|
ip_and_mask: 100.2.1.1/24
|
||||||
|
ipv6_and_mask: 2001:100:2:1::1/64
|
||||||
|
state_ipv6: present
|
||||||
|
TenGigabitEthernet 0/7:
|
||||||
|
desc: "Connected to leaf 2"
|
||||||
|
mtu: 9216
|
||||||
|
portmode:
|
||||||
|
admin: up
|
||||||
|
switchport: False
|
||||||
|
ip_and_mask: 100.2.17.1/24
|
||||||
|
ipv6_and_mask: 2001:100:2:11::1/64
|
||||||
|
state_ipv6: present
|
||||||
|
TenGigabitEthernet 0/8:
|
||||||
|
desc: "Connected to leaf 3"
|
||||||
|
mtu: 9216
|
||||||
|
portmode:
|
||||||
|
admin: up
|
||||||
|
switchport: False
|
||||||
|
ip_and_mask: 100.2.33.1/24
|
||||||
|
ipv6_and_mask: 2001:100:2:21::1/64
|
||||||
|
state_ipv6: present
|
||||||
|
TenGigabitEthernet 0/9:
|
||||||
|
desc: "Connected to leaf 4"
|
||||||
|
mtu: 9216
|
||||||
|
portmode:
|
||||||
|
admin: up
|
||||||
|
switchport: False
|
||||||
|
ip_and_mask: 100.2.49.1/24
|
||||||
|
ipv6_and_mask: 2001:100:2:31::1/64
|
||||||
|
state_ipv6: present
|
||||||
|
|
||||||
|
bgp_router_id: "100.0.1.2"
|
||||||
|
bgp_neigh1_remote_asn: 64801
|
||||||
|
bgp_neigh1_ip: "100.2.1.2"
|
||||||
|
bgp_neigh2_remote_asn: 64802
|
||||||
|
bgp_neigh2_ip: "100.2.33.2"
|
||||||
|
bgp_neigh3_remote_asn: 64803
|
||||||
|
bgp_neigh3_ip: "100.2.17.2"
|
||||||
|
bgp_neigh4_remote_asn: 64804
|
||||||
|
bgp_neigh4_ip: "100.2.49.2"
|
||||||
|
bgp_neigh5_remote_asn: 64801
|
||||||
|
bgp_neigh5_ip: "2001:100:2:1::2"
|
||||||
|
bgp_neigh6_remote_asn: 64802
|
||||||
|
bgp_neigh6_ip: "2001:100:2:11::2"
|
||||||
|
bgp_neigh7_remote_asn: 64803
|
||||||
|
bgp_neigh7_ip: "2001:100:2:21::2"
|
||||||
|
bgp_neigh8_remote_asn: 64804
|
||||||
|
bgp_neigh8_ip: "2001:100:2:31::2"
|
20
playbooks/inventory.yaml
Normal file
20
playbooks/inventory.yaml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
spine1 ansible_host=100.94.210.44
|
||||||
|
spine2 ansible_host=10.11.182.26
|
||||||
|
leaf1 ansible_host=10.11.182.27
|
||||||
|
leaf2 ansible_host=10.11.182.28
|
||||||
|
leaf3 ansible_host=10.11.182.29
|
||||||
|
leaf4 ansible_host=10.11.182.30
|
||||||
|
|
||||||
|
[spine]
|
||||||
|
spine1
|
||||||
|
spine2
|
||||||
|
|
||||||
|
[leaf]
|
||||||
|
leaf1
|
||||||
|
leaf2
|
||||||
|
leaf3
|
||||||
|
leaf4
|
||||||
|
|
||||||
|
[datacenter:children]
|
||||||
|
spine
|
||||||
|
leaf
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
# (c) 2016 Red Hat Inc.
|
# (c) 2020 Red Hat Inc.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2017 Dell Inc.
|
# Copyright (c) 2020 Dell Inc.
|
||||||
#
|
#
|
||||||
# This file is part of Ansible
|
# This file is part of Ansible
|
||||||
#
|
#
|
||||||
|
@ -25,9 +25,11 @@ import sys
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
from ansible import constants as C
|
from ansible import constants as C
|
||||||
|
from ansible.module_utils._text import to_text
|
||||||
|
from ansible.module_utils.connection import Connection
|
||||||
from ansible_collections.ansible.netcommon.plugins.action.network import ActionModule as ActionNetworkModule
|
from ansible_collections.ansible.netcommon.plugins.action.network import ActionModule as ActionNetworkModule
|
||||||
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import load_provider
|
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import load_provider
|
||||||
from ansible_collections.dellemc_networking.os9.plugins.module_utils.network.dellos9.dellos9 import dellos9_provider_spec
|
from ansible_collections.dellemc.os9.plugins.module_utils.network.os9 import os9_provider_spec
|
||||||
from ansible.utils.display import Display
|
from ansible.utils.display import Display
|
||||||
|
|
||||||
display = Display()
|
display = Display()
|
||||||
|
@ -39,7 +41,7 @@ class ActionModule(ActionNetworkModule):
|
||||||
del tmp # tmp no longer has any effect
|
del tmp # tmp no longer has any effect
|
||||||
|
|
||||||
module_name = self._task.action.split('.')[-1]
|
module_name = self._task.action.split('.')[-1]
|
||||||
self._config_module = True if module_name == 'dellos9_config' else False
|
self._config_module = True if module_name == 'os9_config' else False
|
||||||
socket_path = None
|
socket_path = None
|
||||||
persistent_connection = self._play_context.connection.split('.')[-1]
|
persistent_connection = self._play_context.connection.split('.')[-1]
|
||||||
|
|
||||||
|
@ -49,10 +51,10 @@ class ActionModule(ActionNetworkModule):
|
||||||
display.warning('provider is unnecessary when using network_cli and will be ignored')
|
display.warning('provider is unnecessary when using network_cli and will be ignored')
|
||||||
del self._task.args['provider']
|
del self._task.args['provider']
|
||||||
elif self._play_context.connection == 'local':
|
elif self._play_context.connection == 'local':
|
||||||
provider = load_provider(dellos9_provider_spec, self._task.args)
|
provider = load_provider(os9_provider_spec, self._task.args)
|
||||||
pc = copy.deepcopy(self._play_context)
|
pc = copy.deepcopy(self._play_context)
|
||||||
pc.connection = 'network_cli'
|
pc.connection = 'network_cli'
|
||||||
pc.network_os = 'dellos9'
|
pc.network_os = 'dellemc.os9.os9'
|
||||||
pc.remote_addr = provider['host'] or self._play_context.remote_addr
|
pc.remote_addr = provider['host'] or self._play_context.remote_addr
|
||||||
pc.port = int(provider['port'] or self._play_context.port or 22)
|
pc.port = int(provider['port'] or self._play_context.port or 22)
|
||||||
pc.remote_user = provider['username'] or self._play_context.connection_user
|
pc.remote_user = provider['username'] or self._play_context.connection_user
|
||||||
|
@ -65,7 +67,7 @@ class ActionModule(ActionNetworkModule):
|
||||||
pc.become_pass = provider['auth_pass']
|
pc.become_pass = provider['auth_pass']
|
||||||
|
|
||||||
display.vvv('using connection plugin %s' % pc.connection, pc.remote_addr)
|
display.vvv('using connection plugin %s' % pc.connection, pc.remote_addr)
|
||||||
connection = self._shared_loader_obj.connection_loader.get('persistent', pc, sys.stdin, task_uuid=self._task._uuid)
|
connection = self._shared_loader_obj.connection_loader.get('persistent', pc, sys.stdin)
|
||||||
connection.set_options(direct={'persistent_command_timeout': command_timeout})
|
connection.set_options(direct={'persistent_command_timeout': command_timeout})
|
||||||
|
|
||||||
socket_path = connection.run()
|
socket_path = connection.run()
|
||||||
|
@ -77,5 +79,17 @@ class ActionModule(ActionNetworkModule):
|
||||||
|
|
||||||
task_vars['ansible_socket'] = socket_path
|
task_vars['ansible_socket'] = socket_path
|
||||||
|
|
||||||
|
# make sure we are in the right cli context which should be
|
||||||
|
# enable mode and not config module
|
||||||
|
if socket_path is None:
|
||||||
|
socket_path = self._connection.socket_path
|
||||||
|
|
||||||
|
conn = Connection(socket_path)
|
||||||
|
out = conn.get_prompt()
|
||||||
|
while to_text(out, errors='surrogate_then_replace').strip().endswith(')#'):
|
||||||
|
display.vvvv('wrong context, sending exit to device', self._play_context.remote_addr)
|
||||||
|
conn.send_command('exit')
|
||||||
|
out = conn.get_prompt()
|
||||||
|
|
||||||
result = super(ActionModule, self).run(task_vars=task_vars)
|
result = super(ActionModule, self).run(task_vars=task_vars)
|
||||||
return result
|
return result
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
# (c) 2017 Red Hat Inc.
|
# (c) 2020 Red Hat Inc.
|
||||||
#
|
#
|
||||||
# (c) 2017 Dell EMC.
|
# (c) 2020 Dell EMC.
|
||||||
#
|
#
|
||||||
# This file is part of Ansible
|
# This file is part of Ansible
|
||||||
#
|
#
|
||||||
|
@ -21,23 +21,22 @@
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = """
|
||||||
---
|
---
|
||||||
cliconf: dellos9
|
cliconf: os9
|
||||||
short_description: Use dellos9 cliconf to run command on Dell OS9 platform
|
short_description: Use os9 cliconf to run command on Dell OS9 platform
|
||||||
description:
|
description:
|
||||||
- This dellos9 plugin provides low level abstraction apis for
|
- This os9 plugin provides low level abstraction apis for
|
||||||
sending and receiving CLI commands from Dell OS9 network devices.
|
sending and receiving CLI commands from Dell OS9 network devices.
|
||||||
'''
|
version_added: 2.5
|
||||||
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
from ansible.errors import AnsibleConnectionFailure
|
|
||||||
from ansible.module_utils._text import to_bytes, to_text
|
from ansible.module_utils._text import to_bytes, to_text
|
||||||
from ansible.module_utils.common._collections_compat import Mapping
|
|
||||||
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import to_list
|
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import to_list
|
||||||
from ansible.plugins.cliconf import CliconfBase, enable_mode
|
from ansible.plugins.cliconf import CliconfBase, enable_mode
|
||||||
|
|
||||||
|
@ -47,7 +46,7 @@ class Cliconf(CliconfBase):
|
||||||
def get_device_info(self):
|
def get_device_info(self):
|
||||||
device_info = {}
|
device_info = {}
|
||||||
|
|
||||||
device_info['network_os'] = 'dellos9'
|
device_info['network_os'] = 'dellemc.os9.os9'
|
||||||
reply = self.get('show version')
|
reply = self.get('show version')
|
||||||
data = to_text(reply, errors='surrogate_or_strict').strip()
|
data = to_text(reply, errors='surrogate_or_strict').strip()
|
||||||
|
|
||||||
|
@ -88,35 +87,3 @@ class Cliconf(CliconfBase):
|
||||||
def get_capabilities(self):
|
def get_capabilities(self):
|
||||||
result = super(Cliconf, self).get_capabilities()
|
result = super(Cliconf, self).get_capabilities()
|
||||||
return json.dumps(result)
|
return json.dumps(result)
|
||||||
|
|
||||||
def run_commands(self, commands=None, check_rc=True):
|
|
||||||
if commands is None:
|
|
||||||
raise ValueError("'commands' value is required")
|
|
||||||
|
|
||||||
responses = list()
|
|
||||||
for cmd in to_list(commands):
|
|
||||||
if not isinstance(cmd, Mapping):
|
|
||||||
cmd = {'command': cmd}
|
|
||||||
|
|
||||||
output = cmd.pop('output', None)
|
|
||||||
if output:
|
|
||||||
raise ValueError("'output' value %s is not supported for run_commands" % output)
|
|
||||||
|
|
||||||
try:
|
|
||||||
out = self.send_command(**cmd)
|
|
||||||
except AnsibleConnectionFailure as e:
|
|
||||||
if check_rc:
|
|
||||||
raise
|
|
||||||
out = getattr(e, 'err', to_text(e))
|
|
||||||
|
|
||||||
responses.append(out)
|
|
||||||
|
|
||||||
return responses
|
|
||||||
|
|
||||||
def set_cli_prompt_context(self):
|
|
||||||
"""
|
|
||||||
Make sure we are in the operational cli mode
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
if self._connection.connected:
|
|
||||||
self._update_cli_prompt_context(config_context=')#')
|
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Copyright: (c) 2015, Peter Sprygada <psprygada@ansible.com>
|
# Copyright: (c) 2020, Peter Sprygada <psprygada@ansible.com>
|
||||||
# Copyright: (c) 2016, Dell Inc.
|
# Copyright: (c) 2020, Dell Inc.
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
|
0
plugins/module_utils/network/__init__.py
Normal file
0
plugins/module_utils/network/__init__.py
Normal file
|
@ -1,8 +1,8 @@
|
||||||
#
|
#
|
||||||
# (c) 2015 Peter Sprygada, <psprygada@ansible.com>
|
# (c) 2020 Peter Sprygada, <psprygada@ansible.com>
|
||||||
# (c) 2017 Red Hat, Inc
|
# (c) 2020 Red Hat, Inc
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016 Dell Inc.
|
# Copyright (c) 2020 Dell Inc.
|
||||||
#
|
#
|
||||||
# This code is part of Ansible, but is an independent component.
|
# This code is part of Ansible, but is an independent component.
|
||||||
# This particular file snippet, and this file snippet only, is BSD licensed.
|
# This particular file snippet, and this file snippet only, is BSD licensed.
|
||||||
|
@ -29,12 +29,12 @@
|
||||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#
|
#
|
||||||
import json
|
import re
|
||||||
|
|
||||||
from ansible.module_utils._text import to_text
|
from ansible.module_utils._text import to_text
|
||||||
from ansible.module_utils.basic import env_fallback
|
from ansible.module_utils.basic import env_fallback
|
||||||
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import to_list, ComplexList
|
from ansible.module_utils.network.common.utils import to_list, ComplexList
|
||||||
from ansible.module_utils.connection import Connection, ConnectionError, exec_command
|
from ansible.module_utils.connection import exec_command
|
||||||
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.config import NetworkConfig, ConfigLine
|
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.config import NetworkConfig, ConfigLine
|
||||||
|
|
||||||
_DEVICE_CONFIGS = {}
|
_DEVICE_CONFIGS = {}
|
||||||
|
@ -45,7 +45,7 @@ WARNING_PROMPTS_RE = [
|
||||||
r"[\r\n]?\[yes/no\]:\s?$"
|
r"[\r\n]?\[yes/no\]:\s?$"
|
||||||
]
|
]
|
||||||
|
|
||||||
dellos9_provider_spec = {
|
os9_provider_spec = {
|
||||||
'host': dict(),
|
'host': dict(),
|
||||||
'port': dict(type='int'),
|
'port': dict(type='int'),
|
||||||
'username': dict(fallback=(env_fallback, ['ANSIBLE_NET_USERNAME'])),
|
'username': dict(fallback=(env_fallback, ['ANSIBLE_NET_USERNAME'])),
|
||||||
|
@ -55,10 +55,10 @@ dellos9_provider_spec = {
|
||||||
'auth_pass': dict(fallback=(env_fallback, ['ANSIBLE_NET_AUTH_PASS']), no_log=True),
|
'auth_pass': dict(fallback=(env_fallback, ['ANSIBLE_NET_AUTH_PASS']), no_log=True),
|
||||||
'timeout': dict(type='int'),
|
'timeout': dict(type='int'),
|
||||||
}
|
}
|
||||||
dellos9_argument_spec = {
|
os9_argument_spec = {
|
||||||
'provider': dict(type='dict', options=dellos9_provider_spec),
|
'provider': dict(type='dict', options=os9_provider_spec),
|
||||||
}
|
}
|
||||||
dellos9_top_spec = {
|
os9_top_spec = {
|
||||||
'host': dict(removed_in_version=2.9),
|
'host': dict(removed_in_version=2.9),
|
||||||
'port': dict(removed_in_version=2.9, type='int'),
|
'port': dict(removed_in_version=2.9, type='int'),
|
||||||
'username': dict(removed_in_version=2.9),
|
'username': dict(removed_in_version=2.9),
|
||||||
|
@ -68,36 +68,7 @@ dellos9_top_spec = {
|
||||||
'auth_pass': dict(removed_in_version=2.9, no_log=True),
|
'auth_pass': dict(removed_in_version=2.9, no_log=True),
|
||||||
'timeout': dict(removed_in_version=2.9, type='int'),
|
'timeout': dict(removed_in_version=2.9, type='int'),
|
||||||
}
|
}
|
||||||
dellos9_argument_spec.update(dellos9_top_spec)
|
os9_argument_spec.update(os9_top_spec)
|
||||||
|
|
||||||
|
|
||||||
def get_provider_argspec():
|
|
||||||
return dellos9_provider_spec
|
|
||||||
|
|
||||||
|
|
||||||
def get_connection(module):
|
|
||||||
if hasattr(module, '_dellos9_connection'):
|
|
||||||
return module._dellos9_connection
|
|
||||||
|
|
||||||
capabilities = get_capabilities(module)
|
|
||||||
network_api = capabilities.get('network_api')
|
|
||||||
if network_api == 'cliconf':
|
|
||||||
module._dellos9_connection = Connection(module._socket_path)
|
|
||||||
else:
|
|
||||||
module.fail_json(msg='Invalid connection type %s' % network_api)
|
|
||||||
|
|
||||||
return module._dellos9_connection
|
|
||||||
|
|
||||||
|
|
||||||
def get_capabilities(module):
|
|
||||||
if hasattr(module, '_dellos9_capabilities'):
|
|
||||||
return module._dellos9_capabilities
|
|
||||||
try:
|
|
||||||
capabilities = Connection(module._socket_path).get_capabilities()
|
|
||||||
except ConnectionError as exc:
|
|
||||||
module.fail_json(msg=to_text(exc, errors='surrogate_then_replace'))
|
|
||||||
module._dellos9_capabilities = json.loads(capabilities)
|
|
||||||
return module._dellos9_capabilities
|
|
||||||
|
|
||||||
|
|
||||||
def check_args(module, warnings):
|
def check_args(module, warnings):
|
||||||
|
@ -122,12 +93,26 @@ def get_config(module, flags=None):
|
||||||
return cfg
|
return cfg
|
||||||
|
|
||||||
|
|
||||||
|
def to_commands(module, commands):
|
||||||
|
spec = {
|
||||||
|
'command': dict(key=True),
|
||||||
|
'prompt': dict(),
|
||||||
|
'answer': dict()
|
||||||
|
}
|
||||||
|
transform = ComplexList(spec, module)
|
||||||
|
return transform(commands)
|
||||||
|
|
||||||
|
|
||||||
def run_commands(module, commands, check_rc=True):
|
def run_commands(module, commands, check_rc=True):
|
||||||
connection = get_connection(module)
|
responses = list()
|
||||||
try:
|
commands = to_commands(module, to_list(commands))
|
||||||
return connection.run_commands(commands=commands, check_rc=check_rc)
|
for cmd in commands:
|
||||||
except ConnectionError as exc:
|
cmd = module.jsonify(cmd)
|
||||||
module.fail_json(msg=to_text(exc))
|
rc, out, err = exec_command(module, cmd)
|
||||||
|
if check_rc and rc != 0:
|
||||||
|
module.fail_json(msg=to_text(err, errors='surrogate_or_strict'), rc=rc)
|
||||||
|
responses.append(to_text(out, errors='surrogate_or_strict'))
|
||||||
|
return responses
|
||||||
|
|
||||||
|
|
||||||
def load_config(module, commands):
|
def load_config(module, commands):
|
|
@ -1,8 +1,8 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Copyright: (c) 2015, Peter Sprygada <psprygada@ansible.com>
|
# Copyright: (c) 2020, Peter Sprygada <psprygada@ansible.com>
|
||||||
# Copyright: (c) 2016, Dell Inc.
|
# Copyright: (c) 2020, Dell Inc.
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,9 +14,10 @@ ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||||
'status': ['preview'],
|
'status': ['preview'],
|
||||||
'supported_by': 'community'}
|
'supported_by': 'community'}
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = """
|
||||||
---
|
---
|
||||||
module: dellos9_command
|
module: os9_command
|
||||||
|
version_added: "2.2"
|
||||||
author: "Dhivya P (@dhivyap)"
|
author: "Dhivya P (@dhivyap)"
|
||||||
short_description: Run commands on remote devices running Dell OS9
|
short_description: Run commands on remote devices running Dell OS9
|
||||||
description:
|
description:
|
||||||
|
@ -25,22 +26,16 @@ description:
|
||||||
argument that will cause the module to wait for a specific condition
|
argument that will cause the module to wait for a specific condition
|
||||||
before returning or timing out if the condition is not met.
|
before returning or timing out if the condition is not met.
|
||||||
- This module does not support running commands in configuration mode.
|
- This module does not support running commands in configuration mode.
|
||||||
Please use M(dellos9_config) to configure Dell OS9 devices.
|
Please use M(os9_config) to configure Dell OS9 devices.
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment: os9
|
||||||
- dellemc_networking.os9.dellos9
|
|
||||||
|
|
||||||
options:
|
options:
|
||||||
commands:
|
commands:
|
||||||
description:
|
description:
|
||||||
- List of commands to send to the remote dellos9 device over the
|
- List of commands to send to the remote os9 device over the
|
||||||
configured provider. The resulting output from the command
|
configured provider. The resulting output from the command
|
||||||
is returned. If the I(wait_for) argument is provided, the
|
is returned. If the I(wait_for) argument is provided, the
|
||||||
module is not returned until the condition is satisfied or
|
module is not returned until the condition is satisfied or
|
||||||
the number of retries has expired. If a command sent to the
|
the number of retries has expired.
|
||||||
device requires answering a prompt, it is possible to pass
|
|
||||||
a dict containing I(command), I(answer) and I(prompt).
|
|
||||||
Common answers are 'yes' or "\r" (carriage return, must be
|
|
||||||
double quotes). See examples.
|
|
||||||
type: list
|
type: list
|
||||||
required: true
|
required: true
|
||||||
wait_for:
|
wait_for:
|
||||||
|
@ -48,9 +43,10 @@ options:
|
||||||
- List of conditions to evaluate against the output of the
|
- List of conditions to evaluate against the output of the
|
||||||
command. The task will wait for each condition to be true
|
command. The task will wait for each condition to be true
|
||||||
before moving forward. If the conditional is not true
|
before moving forward. If the conditional is not true
|
||||||
within the configured number of retries, the task fails.
|
within the configured number of I(retries), the task fails.
|
||||||
See examples.
|
See examples.
|
||||||
type: list
|
type: list
|
||||||
|
version_added: "2.2"
|
||||||
match:
|
match:
|
||||||
description:
|
description:
|
||||||
- The I(match) argument is used in conjunction with the
|
- The I(match) argument is used in conjunction with the
|
||||||
|
@ -61,7 +57,8 @@ options:
|
||||||
satisfied.
|
satisfied.
|
||||||
type: str
|
type: str
|
||||||
default: all
|
default: all
|
||||||
choices: [ 'all', 'any' ]
|
choices: [ all, any ]
|
||||||
|
version_added: "2.5"
|
||||||
retries:
|
retries:
|
||||||
description:
|
description:
|
||||||
- Specifies the number of retries a command should be tried
|
- Specifies the number of retries a command should be tried
|
||||||
|
@ -78,49 +75,36 @@ options:
|
||||||
trying the command again.
|
trying the command again.
|
||||||
type: int
|
type: int
|
||||||
default: 1
|
default: 1
|
||||||
|
|
||||||
notes:
|
notes:
|
||||||
- This module requires Dell OS9 version 9.10.0.1P13 or above.
|
- This module requires Dell OS9 version 9.10.0.1P13 or above.
|
||||||
|
|
||||||
- This module requires to increase the ssh connection rate limit.
|
- This module requires to increase the ssh connection rate limit.
|
||||||
Use the following command I(ip ssh connection-rate-limit 60)
|
Use the following command I(ip ssh connection-rate-limit 60)
|
||||||
to configure the same. This can be done via M(dellos9_config) module
|
to configure the same. This can be done via M(os9_config) module
|
||||||
as well.
|
as well.
|
||||||
|
"""
|
||||||
'''
|
|
||||||
|
|
||||||
EXAMPLES = """
|
EXAMPLES = """
|
||||||
tasks:
|
tasks:
|
||||||
- name: run show version on remote devices
|
- name: run show version on remote devices
|
||||||
dellos9_command:
|
os9_command:
|
||||||
commands: show version
|
commands: show version
|
||||||
|
|
||||||
- name: run show version and check to see if output contains OS9
|
- name: run show version and check to see if output contains OS9
|
||||||
dellos9_command:
|
os9_command:
|
||||||
commands: show version
|
commands: show version
|
||||||
wait_for: result[0] contains OS9
|
wait_for: result[0] contains OS9
|
||||||
|
|
||||||
- name: run multiple commands on remote nodes
|
- name: run multiple commands on remote nodes
|
||||||
dellos9_command:
|
os9_command:
|
||||||
commands:
|
commands:
|
||||||
- show version
|
- show version
|
||||||
- show interfaces
|
- show interfaces
|
||||||
|
|
||||||
- name: run multiple commands and evaluate the output
|
- name: run multiple commands and evaluate the output
|
||||||
dellos9_command:
|
os9_command:
|
||||||
commands:
|
commands:
|
||||||
- show version
|
- show version
|
||||||
- show interfaces
|
- show interfaces
|
||||||
wait_for:
|
wait_for:
|
||||||
- result[0] contains OS9
|
- result[0] contains OS9
|
||||||
- result[1] contains Loopback
|
- result[1] contains Loopback
|
||||||
|
|
||||||
- name: run commands that require answering a prompt
|
|
||||||
dellos9_command:
|
|
||||||
commands:
|
|
||||||
- command: 'copy running-config startup-config'
|
|
||||||
prompt: '[confirm yes/no]: ?$'
|
|
||||||
answer: 'yes'
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
RETURN = """
|
RETURN = """
|
||||||
|
@ -147,26 +131,39 @@ warnings:
|
||||||
"""
|
"""
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from ansible.module_utils._text import to_text
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible_collections.dellemc.os9.plugins.module_utils.network.os9 import run_commands
|
||||||
|
from ansible_collections.dellemc.os9.plugins.module_utils.network.os9 import os9_argument_spec, check_args
|
||||||
|
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ComplexList
|
||||||
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.parsing import Conditional
|
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.parsing import Conditional
|
||||||
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import transform_commands, to_lines
|
from ansible.module_utils.six import string_types
|
||||||
from ansible_collections.dellemc_networking.os9.plugins.module_utils.network.dellos9.dellos9 import run_commands
|
|
||||||
from ansible_collections.dellemc_networking.os9.plugins.module_utils.network.dellos9.dellos9 import dellos9_argument_spec, check_args
|
|
||||||
|
def to_lines(stdout):
|
||||||
|
for item in stdout:
|
||||||
|
if isinstance(item, string_types):
|
||||||
|
item = str(item).split('\n')
|
||||||
|
yield item
|
||||||
|
|
||||||
|
|
||||||
def parse_commands(module, warnings):
|
def parse_commands(module, warnings):
|
||||||
commands = transform_commands(module)
|
command = ComplexList(dict(
|
||||||
|
command=dict(key=True),
|
||||||
if module.check_mode:
|
prompt=dict(),
|
||||||
for item in list(commands):
|
answer=dict()
|
||||||
if not item['command'].startswith('show'):
|
), module)
|
||||||
|
commands = command(module.params['commands'])
|
||||||
|
for index, item in enumerate(commands):
|
||||||
|
if module.check_mode and not item['command'].startswith('show'):
|
||||||
warnings.append(
|
warnings.append(
|
||||||
'Only show commands are supported when using check mode, not '
|
'only show commands are supported when using check mode, not '
|
||||||
'executing %s' % item['command']
|
'executing `%s`' % item['command']
|
||||||
|
)
|
||||||
|
elif item['command'].startswith('conf'):
|
||||||
|
module.fail_json(
|
||||||
|
msg='os9_command does not support running config mode '
|
||||||
|
'commands. Please use os9_config instead'
|
||||||
)
|
)
|
||||||
commands.remove(item)
|
|
||||||
|
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
|
|
||||||
|
@ -184,7 +181,7 @@ def main():
|
||||||
interval=dict(default=1, type='int')
|
interval=dict(default=1, type='int')
|
||||||
)
|
)
|
||||||
|
|
||||||
argument_spec.update(dellos9_argument_spec)
|
argument_spec.update(os9_argument_spec)
|
||||||
|
|
||||||
module = AnsibleModule(argument_spec=argument_spec,
|
module = AnsibleModule(argument_spec=argument_spec,
|
||||||
supports_check_mode=True)
|
supports_check_mode=True)
|
||||||
|
@ -197,11 +194,8 @@ def main():
|
||||||
result['warnings'] = warnings
|
result['warnings'] = warnings
|
||||||
|
|
||||||
wait_for = module.params['wait_for'] or list()
|
wait_for = module.params['wait_for'] or list()
|
||||||
|
|
||||||
try:
|
|
||||||
conditionals = [Conditional(c) for c in wait_for]
|
conditionals = [Conditional(c) for c in wait_for]
|
||||||
except AttributeError as exc:
|
|
||||||
module.fail_json(msg=to_text(exc))
|
|
||||||
retries = module.params['retries']
|
retries = module.params['retries']
|
||||||
interval = module.params['interval']
|
interval = module.params['interval']
|
||||||
match = module.params['match']
|
match = module.params['match']
|
||||||
|
@ -228,6 +222,7 @@ def main():
|
||||||
module.fail_json(msg=msg, failed_conditions=failed_conditions)
|
module.fail_json(msg=msg, failed_conditions=failed_conditions)
|
||||||
|
|
||||||
result.update({
|
result.update({
|
||||||
|
'changed': False,
|
||||||
'stdout': responses,
|
'stdout': responses,
|
||||||
'stdout_lines': list(to_lines(responses))
|
'stdout_lines': list(to_lines(responses))
|
||||||
})
|
})
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
#
|
#
|
||||||
# (c) 2015 Peter Sprygada, <psprygada@ansible.com>
|
# (c) 2020 Peter Sprygada, <psprygada@ansible.com>
|
||||||
# Copyright (c) 2016 Dell Inc.
|
# Copyright (c) 2020 Dell Inc.
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
from __future__ import absolute_import, division, print_function
|
from __future__ import absolute_import, division, print_function
|
||||||
|
@ -13,9 +13,10 @@ ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||||
'supported_by': 'community'}
|
'supported_by': 'community'}
|
||||||
|
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = """
|
||||||
---
|
---
|
||||||
module: dellos9_config
|
module: os9_config
|
||||||
|
version_added: "2.2"
|
||||||
author: "Dhivya P (@dhivyap)"
|
author: "Dhivya P (@dhivyap)"
|
||||||
short_description: Manage Dell EMC Networking OS9 configuration sections
|
short_description: Manage Dell EMC Networking OS9 configuration sections
|
||||||
description:
|
description:
|
||||||
|
@ -23,9 +24,7 @@ description:
|
||||||
for segmenting configuration into sections. This module provides
|
for segmenting configuration into sections. This module provides
|
||||||
an implementation for working with OS9 configuration sections in
|
an implementation for working with OS9 configuration sections in
|
||||||
a deterministic way.
|
a deterministic way.
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment: os9
|
||||||
- dellemc_networking.os9.dellos9
|
|
||||||
|
|
||||||
options:
|
options:
|
||||||
lines:
|
lines:
|
||||||
description:
|
description:
|
||||||
|
@ -127,7 +126,7 @@ options:
|
||||||
suboptions:
|
suboptions:
|
||||||
filename:
|
filename:
|
||||||
description:
|
description:
|
||||||
- The filename to be used to store the backup configuration. If the filename
|
- The filename to be used to store the backup configuration. If the the filename
|
||||||
is not given it will be generated based on the hostname, current time and date
|
is not given it will be generated based on the hostname, current time and date
|
||||||
in format defined by <hostname>_config.<current-date>@<current-time>
|
in format defined by <hostname>_config.<current-date>@<current-time>
|
||||||
dir_path:
|
dir_path:
|
||||||
|
@ -140,21 +139,20 @@ options:
|
||||||
and backup configuration will be copied in C(filename) within I(backup) directory.
|
and backup configuration will be copied in C(filename) within I(backup) directory.
|
||||||
type: path
|
type: path
|
||||||
type: dict
|
type: dict
|
||||||
|
version_added: "2.8"
|
||||||
notes:
|
notes:
|
||||||
- This module requires Dell OS9 version 9.10.0.1P13 or above.
|
- This module requires Dell OS9 version 9.10.0.1P13 or above.
|
||||||
|
|
||||||
- This module requires to increase the ssh connection rate limit.
|
- This module requires to increase the ssh connection rate limit.
|
||||||
Use the following command I(ip ssh connection-rate-limit 60)
|
Use the following command I(ip ssh connection-rate-limit 60)
|
||||||
to configure the same. This can also be done with the
|
to configure the same. This can also be done with the
|
||||||
M(dellos9_config) module.
|
M(os9_config) module.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
EXAMPLES = """
|
EXAMPLES = """
|
||||||
- dellos9_config:
|
- os9_config:
|
||||||
lines: ['hostname {{ inventory_hostname }}']
|
lines: ['hostname {{ inventory_hostname }}']
|
||||||
provider: "{{ cli }}"
|
provider: "{{ cli }}"
|
||||||
|
- os9_config:
|
||||||
- dellos9_config:
|
|
||||||
lines:
|
lines:
|
||||||
- 10 permit ip host 1.1.1.1 any log
|
- 10 permit ip host 1.1.1.1 any log
|
||||||
- 20 permit ip host 2.2.2.2 any log
|
- 20 permit ip host 2.2.2.2 any log
|
||||||
|
@ -164,8 +162,7 @@ EXAMPLES = """
|
||||||
parents: ['ip access-list extended test']
|
parents: ['ip access-list extended test']
|
||||||
before: ['no ip access-list extended test']
|
before: ['no ip access-list extended test']
|
||||||
match: exact
|
match: exact
|
||||||
|
- os9_config:
|
||||||
- dellos9_config:
|
|
||||||
lines:
|
lines:
|
||||||
- 10 permit ip host 1.1.1.1 any log
|
- 10 permit ip host 1.1.1.1 any log
|
||||||
- 20 permit ip host 2.2.2.2 any log
|
- 20 permit ip host 2.2.2.2 any log
|
||||||
|
@ -174,8 +171,7 @@ EXAMPLES = """
|
||||||
parents: ['ip access-list extended test']
|
parents: ['ip access-list extended test']
|
||||||
before: ['no ip access-list extended test']
|
before: ['no ip access-list extended test']
|
||||||
replace: block
|
replace: block
|
||||||
|
- os9_config:
|
||||||
- dellos9_config:
|
|
||||||
lines: ['hostname {{ inventory_hostname }}']
|
lines: ['hostname {{ inventory_hostname }}']
|
||||||
provider: "{{ cli }}"
|
provider: "{{ cli }}"
|
||||||
backup: yes
|
backup: yes
|
||||||
|
@ -205,13 +201,13 @@ backup_path:
|
||||||
description: The full path to the backup file
|
description: The full path to the backup file
|
||||||
returned: when backup is yes
|
returned: when backup is yes
|
||||||
type: str
|
type: str
|
||||||
sample: /playbooks/ansible/backup/dellos9_config.2016-07-16@22:28:34
|
sample: /playbooks/ansible/backup/os9_config.2016-07-16@22:28:34
|
||||||
"""
|
"""
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible_collections.dellemc_networking.os9.plugins.module_utils.network.dellos9.dellos9 import get_config, get_sublevel_config
|
from ansible_collections.dellemc.os9.plugins.module_utils.network.os9 import get_config, get_sublevel_config
|
||||||
from ansible_collections.dellemc_networking.os9.plugins.module_utils.network.dellos9.dellos9 import dellos9_argument_spec, check_args
|
from ansible_collections.dellemc.os9.plugins.module_utils.network.os9 import os9_argument_spec, check_args
|
||||||
from ansible_collections.dellemc_networking.os9.plugins.module_utils.network.dellos9.dellos9 import load_config, run_commands
|
from ansible_collections.dellemc.os9.plugins.module_utils.network.os9 import load_config, run_commands
|
||||||
from ansible_collections.dellemc_networking.os9.plugins.module_utils.network.dellos9.dellos9 import WARNING_PROMPTS_RE
|
from ansible_collections.dellemc.os9.plugins.module_utils.network.os9 import WARNING_PROMPTS_RE
|
||||||
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.config import NetworkConfig, dumps
|
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.config import NetworkConfig, dumps
|
||||||
|
|
||||||
|
|
||||||
|
@ -264,7 +260,7 @@ def main():
|
||||||
backup_options=dict(type='dict', options=backup_spec)
|
backup_options=dict(type='dict', options=backup_spec)
|
||||||
)
|
)
|
||||||
|
|
||||||
argument_spec.update(dellos9_argument_spec)
|
argument_spec.update(os9_argument_spec)
|
||||||
|
|
||||||
mutually_exclusive = [('lines', 'src'),
|
mutually_exclusive = [('lines', 'src'),
|
||||||
('parents', 'src')]
|
('parents', 'src')]
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
#
|
#
|
||||||
# (c) 2015 Peter Sprygada, <psprygada@ansible.com>
|
# (c) 2020 Peter Sprygada, <psprygada@ansible.com>
|
||||||
# Copyright (c) 2016 Dell Inc.
|
# Copyright (c) 2020 Dell Inc.
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
from __future__ import absolute_import, division, print_function
|
from __future__ import absolute_import, division, print_function
|
||||||
|
@ -13,9 +13,10 @@ ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||||
'supported_by': 'community'}
|
'supported_by': 'community'}
|
||||||
|
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = """
|
||||||
---
|
---
|
||||||
module: dellos9_facts
|
module: os9_facts
|
||||||
|
version_added: "2.2"
|
||||||
author: "Dhivya P (@dhivyap)"
|
author: "Dhivya P (@dhivyap)"
|
||||||
short_description: Collect facts from remote devices running Dell EMC Networking OS9
|
short_description: Collect facts from remote devices running Dell EMC Networking OS9
|
||||||
description:
|
description:
|
||||||
|
@ -24,9 +25,7 @@ description:
|
||||||
base network fact keys with C(ansible_net_<fact>). The facts
|
base network fact keys with C(ansible_net_<fact>). The facts
|
||||||
module will always collect a base set of facts from the device
|
module will always collect a base set of facts from the device
|
||||||
and can enable or disable collection of additional facts.
|
and can enable or disable collection of additional facts.
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment: os9
|
||||||
- dellemc_networking.os9.dellos9
|
|
||||||
|
|
||||||
options:
|
options:
|
||||||
gather_subset:
|
gather_subset:
|
||||||
description:
|
description:
|
||||||
|
@ -39,24 +38,21 @@ options:
|
||||||
default: [ '!config' ]
|
default: [ '!config' ]
|
||||||
notes:
|
notes:
|
||||||
- This module requires OS9 version 9.10.0.1P13 or above.
|
- This module requires OS9 version 9.10.0.1P13 or above.
|
||||||
|
|
||||||
- This module requires an increase of the SSH connection rate limit.
|
- This module requires an increase of the SSH connection rate limit.
|
||||||
Use the following command I(ip ssh connection-rate-limit 60)
|
Use the following command I(ip ssh connection-rate-limit 60)
|
||||||
to configure the same. This can be also be done with the M(dellos9_config) module.
|
to configure the same. This can be also be done with the M(os9_config) module.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
EXAMPLES = """
|
EXAMPLES = """
|
||||||
# Collect all facts from the device
|
# Collect all facts from the device
|
||||||
- dellos9_facts:
|
- os9_facts:
|
||||||
gather_subset: all
|
gather_subset: all
|
||||||
|
|
||||||
# Collect only the config and default facts
|
# Collect only the config and default facts
|
||||||
- dellos9_facts:
|
- os9_facts:
|
||||||
gather_subset:
|
gather_subset:
|
||||||
- config
|
- config
|
||||||
|
|
||||||
# Do not collect hardware facts
|
# Do not collect hardware facts
|
||||||
- dellos9_facts:
|
- os9_facts:
|
||||||
gather_subset:
|
gather_subset:
|
||||||
- "!hardware"
|
- "!hardware"
|
||||||
"""
|
"""
|
||||||
|
@ -66,7 +62,6 @@ ansible_net_gather_subset:
|
||||||
description: The list of fact subsets collected from the device
|
description: The list of fact subsets collected from the device
|
||||||
returned: always
|
returned: always
|
||||||
type: list
|
type: list
|
||||||
|
|
||||||
# default
|
# default
|
||||||
ansible_net_model:
|
ansible_net_model:
|
||||||
description: The model name returned from the device
|
description: The model name returned from the device
|
||||||
|
@ -88,7 +83,6 @@ ansible_net_image:
|
||||||
description: The image file the device is running
|
description: The image file the device is running
|
||||||
returned: always
|
returned: always
|
||||||
type: str
|
type: str
|
||||||
|
|
||||||
# hardware
|
# hardware
|
||||||
ansible_net_filesystems:
|
ansible_net_filesystems:
|
||||||
description: All file system names available on the device
|
description: All file system names available on the device
|
||||||
|
@ -102,13 +96,11 @@ ansible_net_memtotal_mb:
|
||||||
description: The total memory on the remote device in Mb
|
description: The total memory on the remote device in Mb
|
||||||
returned: when hardware is configured
|
returned: when hardware is configured
|
||||||
type: int
|
type: int
|
||||||
|
|
||||||
# config
|
# config
|
||||||
ansible_net_config:
|
ansible_net_config:
|
||||||
description: The current active config from the device
|
description: The current active config from the device
|
||||||
returned: when config is configured
|
returned: when config is configured
|
||||||
type: str
|
type: str
|
||||||
|
|
||||||
# interfaces
|
# interfaces
|
||||||
ansible_net_all_ipv4_addresses:
|
ansible_net_all_ipv4_addresses:
|
||||||
description: All IPv4 addresses configured on the device
|
description: All IPv4 addresses configured on the device
|
||||||
|
@ -134,8 +126,8 @@ except ImportError:
|
||||||
izip = zip
|
izip = zip
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible_collections.dellemc_networking.os9.plugins.module_utils.network.dellos9.dellos9 import run_commands
|
from ansible_collections.dellemc.os9.plugins.module_utils.network.os9 import run_commands
|
||||||
from ansible_collections.dellemc_networking.os9.plugins.module_utils.network.dellos9.dellos9 import dellos9_argument_spec, check_args
|
from ansible_collections.dellemc.os9.plugins.module_utils.network.os9 import os9_argument_spec, check_args
|
||||||
from ansible.module_utils.six import iteritems
|
from ansible.module_utils.six import iteritems
|
||||||
|
|
||||||
|
|
||||||
|
@ -511,7 +503,7 @@ def main():
|
||||||
gather_subset=dict(default=['!config'], type='list')
|
gather_subset=dict(default=['!config'], type='list')
|
||||||
)
|
)
|
||||||
|
|
||||||
argument_spec.update(dellos9_argument_spec)
|
argument_spec.update(os9_argument_spec)
|
||||||
|
|
||||||
module = AnsibleModule(argument_spec=argument_spec,
|
module = AnsibleModule(argument_spec=argument_spec,
|
||||||
supports_check_mode=True)
|
supports_check_mode=True)
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
# (c) 2016 Red Hat Inc.
|
# (c) 2020 Red Hat Inc.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2017 Dell Inc.
|
# Copyright (c) 2020 Dell Inc.
|
||||||
#
|
#
|
||||||
# This file is part of Ansible
|
# This file is part of Ansible
|
||||||
#
|
#
|
201
roles/os9_aaa/LICENSE
Normal file
201
roles/os9_aaa/LICENSE
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright (c) 2020, Dell EMC. All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
334
roles/os9_aaa/README.md
Normal file
334
roles/os9_aaa/README.md
Normal file
|
@ -0,0 +1,334 @@
|
||||||
|
AAA role
|
||||||
|
========
|
||||||
|
|
||||||
|
This role facilitates the configuration of authentication authorization acccounting (AAA). It supports the configuration of TACACS for OS9. The AAA role requires an SSH connection for connectivity to a Dell EMC Networking device. You can use any of the built-in OS connection variables .
|
||||||
|
|
||||||
|
|
||||||
|
Role variables
|
||||||
|
--------------
|
||||||
|
|
||||||
|
- Role is abstracted using the *ansible_network_os* variable that can take dellemc.os9.os9 as a value
|
||||||
|
- If *os9_cfg_generate* is set to true, the variable generates the role configuration commands in a file
|
||||||
|
- Any role variable with a corresponding state variable set to absent negates the configuration of that variable
|
||||||
|
- Setting an empty value for any variable negates the corresponding configuration
|
||||||
|
- Variables and values are case-sensitive
|
||||||
|
|
||||||
|
**os9_aaa keys**
|
||||||
|
|
||||||
|
| Key | Type | Description | Support |
|
||||||
|
|------------|---------------------------|---------------------------------------------------------|-----------------------|
|
||||||
|
| ``radius_server`` | dictionary | Configures the radius server (see ``radius_server.*``) | os9 |
|
||||||
|
| ``radius_server.key`` | string (required): 0,7,LINE | Configures the authentication key for the radius server | os9 |
|
||||||
|
| ``radius_server.key_string`` | string | Configures the user key string; variable takes the hidden user key string if value is 7; variable takes the unencrypted user key (clear-text) if value is 0; variable supported only if *radius_server.key* is 7 or 0 | os9 |
|
||||||
|
| ``radius_server.retransmit`` | integer | Configures the number of retransmissions | os9 |
|
||||||
|
| ``radius_server.timeout`` | integer | Configures the timeout for retransmissions | os9 |
|
||||||
|
| ``radius_server.deadtime`` | integer | Configures the server dead time | os9 |
|
||||||
|
| ``radius_server.group`` | dictionary | Configures the radius servers group (see ``group.*``) | os9 |
|
||||||
|
| ``group.name`` | string (required) | Configures the group name of the radius servers | os9 |
|
||||||
|
| ``group.host`` | dictionary | Configures the radius server host in the group (see ``host.*``) | os9 |
|
||||||
|
| ``host.ip`` | string | Configures the radius server host address in the group | os9 |
|
||||||
|
| ``host.key`` | string (required): 0,7,LINE | Configures the authentication key | os9 |
|
||||||
|
| ``host.key_string`` | string: 7,0 | Configures the user key string; variable takes the hidden user key string if value is 7; variable takes the unencrypted user key (clear-text) if value is 0; variable supported only if *host.key* is 7 or 0 | os9 |
|
||||||
|
| ``host.retransmit`` | integer | Configures the number of retransmissions | os9 |
|
||||||
|
| ``host.auth_port`` | integer | Configures the authentication port (0 to 65535) | os9 |
|
||||||
|
| ``host.timeout`` | integer | Configures the timeout for retransmissions | os9 |
|
||||||
|
| ``host.state`` | string: present,absent | Removes the host from group of radius server if set to absent | os9 |
|
||||||
|
| ``group.vrf`` | dictionary | Configures the VRF for radius servers in the group (see ``vrf.*``) | os9 |
|
||||||
|
| ``vrf.vrf_name`` | string (required) | Configures the name of VRF for the radius server group | os9 |
|
||||||
|
| ``vrf.source_intf`` | integer | Configures the source interface for outgoing packets from servers in the group | os9 |
|
||||||
|
| ``vrf.state`` | string: present,absent | Removes the VRF from group of radius servers if set to absent | os9 |
|
||||||
|
| ``group.state`` | string: present,absent | Removes the radius server group if set to absent | os9 |
|
||||||
|
| ``radius_server.host`` | dictionary | Configures the radius server host (see ``host.*``) | os9 |
|
||||||
|
| ``host.ip`` | string | Configures the radius server host address | os9 |
|
||||||
|
| ``host.key`` | string (required); 0,7,LINE | Configures the authentication key | os9 |
|
||||||
|
| ``host.key_string`` | string | Configures the user key string; variable takes the hidden user key string if value is 7; variable takes the unencrypted user key (clear-text) if value is 0; variable supported only if *host.key* is 7 or 0 | os9 |
|
||||||
|
| ``host.retransmit`` | integer | Configures the number of retransmissions | os9 |
|
||||||
|
| ``host.auth_port`` | integer | Configures the authentication port (0 to 65535) | os9 |
|
||||||
|
| ``host.timeout`` | integer | Configures timeout for retransmissions | os9 |
|
||||||
|
| ``host.state`` | string: present,absent | Removes the radius server host if set to absent | os9 |
|
||||||
|
| ``auth.key`` | string (required); 0,7,LINE | Configures the authentication key | os9 |
|
||||||
|
| ``tacacs_server`` | dictionary | Configures the tacacs server (see ``tacacs_server.*``)| os9 |
|
||||||
|
| ``tacacs_server.key`` | string (required): 0,7,LINE | Configures the authentication key for tacacs server | os9 |
|
||||||
|
| ``tacacs_server.key_string`` | string | Configures the user key string; variable takes the hidden user key string if value is 7; variable takes the unencrypted user key (clear-text) if value is 0; variable supported only if *tacacs_server.key* is 7 or 0 | os9 |
|
||||||
|
| ``tacacs_server.group`` | dictionary | Configures the group of tacacs servers (see ``group.*``) | os9 |
|
||||||
|
| ``group.name`` | string (required) | Configures the group name of the tacacs servers | os9 |
|
||||||
|
| ``group.host`` | dictionary | Configures the tacacs server host in the group (see ``host.*``) | os9 |
|
||||||
|
| ``host.ip`` | string | Configures the tacacs server host address in the group | os9 |
|
||||||
|
| ``host.key`` | string (required): 0,7,LINE | Configures the authentication key of the tacacs server host | os9 |
|
||||||
|
| ``host.key_string`` | string | Configures the user key string; variable takes the hidden user key string if value is 7; variable takes the unencrypted user key (clear-text) if value is 0; variable supported only *host.key* is 7 or 0 | os9 |
|
||||||
|
| ``host.retransmit`` | integer | Configures the number of retransmissions | os9 |
|
||||||
|
| ``host.auth_port`` | integer | Configures the authentication port (0 to 65535) | os9 |
|
||||||
|
| ``host.timeout`` | integer | Configures timeout for retransmissions | os9 |
|
||||||
|
| ``host.state`` | string: present,absent | Removes the host from group of tacacs server if set to absent | os9 |
|
||||||
|
| ``group.vrf`` | dictionary | Configures VRF for tacacs servers in the group (see ``vrf.*``) | os9 |
|
||||||
|
| ``vrf.vrf_name`` | string (required) | Configures the name of VRF for tacacs server group | os9 |
|
||||||
|
| ``vrf.source_intf`` | integer | Configures source interface for outgoing packets from servers in the group | os9 |
|
||||||
|
| ``vrf.state`` | string: present,absent | Removes the VRF from group of tacacs server if set to absent | os9 |
|
||||||
|
| ``group.state`` | string: present,absent | Removes the tacacs server group if set to absent | os9 |
|
||||||
|
| ``tacacs_server.host`` | dictionary | Configures the tacacs server host (see ``host.*``) | os9 |
|
||||||
|
| ``host.ip`` | string | Configures the tacacs sever host address | os9 |
|
||||||
|
| ``host.key`` | string (required): 0,7,LINE | Configures the authentication key | os9 |
|
||||||
|
| ``host.key_string`` | string | Configures the user key string; variable takes the hidden user key string if value is 7; variable takes the unencrypted user key (clear-text) if value is 0; variable supported only if *host.key* is 7 or 0 | os9 |
|
||||||
|
| ``host.retransmit`` | integer | Configures the number of retransmissions | os9 |
|
||||||
|
| ``host.auth_port`` | integer | Configures the authentication port (0 to 65535) | os9 |
|
||||||
|
| ``host.timeout`` | integer | Configures the timeout for retransmissions | os9 |
|
||||||
|
| ``host.state`` | string: present,absent | Removes the tacacs server host if set to absent | os9 |
|
||||||
|
| ``aaa_accounting`` | dictionary | Configures accounting parameters (see ``aaa_accounting.*``) | os9 |
|
||||||
|
| ``aaa_accounting.commands`` | list | Configures accounting for exec (shell) and config commands (see ``commands.*``) | os9 |
|
||||||
|
| ``commands.enable_level`` | integer | Configures enable level for accounting of commands | os9 |
|
||||||
|
| ``commands.role_name`` | string | Configures user role for accounting of commands; variable is mutually exclusive with ``enable_level`` | os9 |
|
||||||
|
| ``commands.accounting_list_name`` | integer | Configures named accounting list for commands | os9 |
|
||||||
|
| ``commands.no_accounting`` | boolean | Configures no accounting of commands | os9 |
|
||||||
|
| ``commands.record_option`` | string: start-stop,stop-only,wait-start | Configures options to record data | os9 |
|
||||||
|
| ``commands.state`` | string: present,absent | Removes the named accounting list for the commands if set to absent | os9 |
|
||||||
|
| ``aaa_accounting.exec`` | list | Configures accounting for EXEC (shell) commands (see ``exec.*``) | os9 |
|
||||||
|
| ``exec.accounting_list_name`` | string | Configures named accounting list for exec commands | os9 |
|
||||||
|
| ``exec.no_accounting`` | boolean | Configures no accounting of EXEC commands | os9 |
|
||||||
|
| ``exec.record_option`` | string: start-stop,stop-only,wait-start | Configures options to record data | os9 |
|
||||||
|
| ``exec.state`` | string: present,absent | Removes the named accounting list for the exec commands if set to absent | os9 |
|
||||||
|
| ``aaa_accounting.suppress`` | boolean | Suppresses accounting for users with NULL username | os9|
|
||||||
|
| ``aaa_accounting.dot1x`` | string: none,start-stop,stop-only,wait-start | Configures accounting for dot1x events | os9 |
|
||||||
|
| ``aaa_accounting.rest`` | string:none,start-stop,stop-only,wait-start | Configures accounting for rest interface events | os9 |
|
||||||
|
| ``aaa_authorization`` | dictionary | Configures authorization parameters (see ``aaa_authorization.*``) | os9 |
|
||||||
|
| ``aaa_authorization.commands`` | list | Configures authorization for EXEC (shell) and config commands (see ``commands.*``)| os9 |
|
||||||
|
| ``commands.enable_level`` | integer | Configures enable level for authorization of commands | os9 |
|
||||||
|
| ``commands.role_name`` | string | Configures user role for authorization of commands; mutually exclusive with ``enable_level`` | os9 |
|
||||||
|
| ``commands.authorization_list_name`` | string | Configures named authorization list for commands | os9 |
|
||||||
|
| ``commands.authorization_method`` | string: none | Configures no authorization of commands | os9 |
|
||||||
|
| ``commands.use_data`` | string: local,tacacs+ | Configures data used for authorization | os9 |
|
||||||
|
| ``commands.state`` | string: present,absent | Removes the named authorization list for the commands if set to absent | os9 |
|
||||||
|
| ``aaa_authorization.config_commands`` | boolean | Configures authorization for configuration mode commands | os9 |
|
||||||
|
| ``aaa_authorization.role_only`` | boolean | Configures validation of authentication mode for user role | os9 |
|
||||||
|
| ``aaa_authorization.exec`` | list | Configures authorization for EXEC (shell) commands (see ``exec.*``) | os9 |
|
||||||
|
| ``exec.authorization_list_name`` | string | Configures named authorization list for EXEC commands | os9 |
|
||||||
|
| ``exec.authorization_method`` | string: none | Configures no authorization of EXEC commands | os9 |
|
||||||
|
| ``exec.use_data`` | string: local,tacacs+ | Configures data used for authorization | os9 |
|
||||||
|
| ``exec.state`` | string: present,absent | Removes the named authorization list for the EXEC commands if set to absent | os9 |
|
||||||
|
| ``aaa_authorization.network`` | string: none,radius,ias | Configures authorization for network events | os9 |
|
||||||
|
| ``aaa_authentication`` | dictionary | Configures authentication parameters (see ``aaa_authentication.*``) | os9 |
|
||||||
|
| ``aaa_radius`` | dictionary | Configures AAA for radius group of servers (see ``aaa_radius.*``) | os9 |
|
||||||
|
| ``aaa_radius.group`` | string | Configures name of the radius group of servers for AAA | os9 |
|
||||||
|
| ``aaa_radius.auth_method`` | string: pap,mschapv2 | Configures authentication method of radius group of servers for AAA | os9 |
|
||||||
|
| ``aaa_tacacs`` | dictionary | Configures AAA for tacacs group of servers (see ``aaa_tacacs.*``) | os9 |
|
||||||
|
| ``aaa_tacacs.group`` | string | Configures name of the tacacs group of servers for AAA | os9 |
|
||||||
|
| ``aaa_authentication.auth_list`` | list | Configures named authentication list for hosts (see ``host.*``) | os9 |
|
||||||
|
| ``auth_list.name`` | string | Configures named authentication list | os9 |
|
||||||
|
| ``auth_list.login_or_enable`` | string: enable,login | Configures authentication list for login or enable | os9 |
|
||||||
|
| ``auth_list.server`` | string: radius,tacacs+ | Configures AAA to use this list of all server hosts | os9 |
|
||||||
|
| ``auth_list.use_password`` | string: line,local,enable,none | Configures password to use for authentication | os9 |
|
||||||
|
| ``auth_list.state`` | string: present,absent | Removes the named authentication list if set to absent | os9 |
|
||||||
|
| ``aaa_authentication.dot1x`` | string: none,radius,ias | Configures authentication for dot1x events | os9 |
|
||||||
|
| ``line_terminal`` | dictionary | Configures the terminal line (see ``line_terminal.*``) | os9 |
|
||||||
|
| ``line_terminal.<terminal>`` | dictionary | Configures the primary or virtual terminal line (see ``<terminal>.*``); value can be console <line_number>, vty <line_number> | os9 |
|
||||||
|
| ``<terminal>.authorization`` | dictionary | Configures authorization parameters of line terminal (see ``authorization.*``) | os9 |
|
||||||
|
| ``authorization.commands`` | list | Configures authorization for EXEC (shell) and config commands (see ``commands.*``) | os9 |
|
||||||
|
| ``commands.enable_level`` | integer | Configures enable level for authorization of commands at line terminal | os9 |
|
||||||
|
| ``commands.role_name`` | string | Configures user role for authorization of commands at line terminal; mutually exclusive with `enable_level` | os9 |
|
||||||
|
| ``commands.authorization_list_name`` | string | Configures named authorization list for commands | os9 |
|
||||||
|
| ``commands.state`` | string: present,absent | Removes the authorization of commands from line terminal if set to absent | os9 |
|
||||||
|
| ``authorization.exec`` | list | Configures authorization for EXEC (shell) commands at line terminal (see ``exec.*``) | os9 |
|
||||||
|
| ``exec.authorization_list_name`` | string | Configures named authorization list for EXEC commands | os9 |
|
||||||
|
| ``exec.state`` | string: present,absent | Removes the authorization of EXEC (shell) from line terminal if set to absent | os9 |
|
||||||
|
| ``<terminal>.accounting`` | dictionary | Configures accounting parameters of line terminal (see ``accounting.*``) | os9 |
|
||||||
|
| ``accounting.commands`` | list | Configures accounting for EXEC (shell) and config commands (see ``commands.*``) | os9 |
|
||||||
|
| ``commands.enable_level`` | integer | Configures enable level for accounting of commands at line terminal | os9|
|
||||||
|
| ``commands.role_name`` | string | Configures user role for accounting of commands at line terminal; mutually exclusive with ``enable_level`` | os9 |
|
||||||
|
| ``commands.accounting_list_name`` | string | Configures named accounting list for commands | os9 |
|
||||||
|
| ``commands.state`` | string: present,absent | Removes the accounting of commands from line terminal if set to absent | os9|
|
||||||
|
| ``accounting.exec`` | list | Configures accounting for EXEC (shell) commands at line terminal (see ``exec.*``) | os9 |
|
||||||
|
| ``exec.accounting_list_name`` | string | Configures named accounting list for EXEC commands | os9 |
|
||||||
|
| ``exec.state`` | string: present,absent | Removes the accounting of EXEC (shell) from line terminal if set to absent | os9 |
|
||||||
|
| ``<terminal>.authentication`` | dictionary | Configures authentication parameters of line terminal (see ``authentication.*``) | os9 |
|
||||||
|
| ``authentication.enable`` | string | Configures the authentication list for privilege-level password authentication | os9 |
|
||||||
|
| ``authentication.login`` | string | Configures the authentication list for password checking | os9 |
|
||||||
|
| ``client.ip`` | string | Configures the client ip for the radius server | os9 |
|
||||||
|
| ``client.key`` | string (required): 0,7,LINE | Configures the authentication key for the radius server | os9 |
|
||||||
|
> **NOTE**: Asterisk (*) denotes the default value if none is specified.
|
||||||
|
|
||||||
|
Connection variables
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Ansible Dell EMC Networking roles require connection information to establish communication with the nodes in your inventory. This information can exist in the Ansible *group_vars* or *host_vars* directories or inventory, or in the playbook itself.
|
||||||
|
|
||||||
|
| Key | Required | Choices | Description |
|
||||||
|
|-------------|----------|------------|-----------------------------------------------------|
|
||||||
|
| ``ansible_host`` | yes | | Specifies the hostname or address for connecting to the remote device over the specified transport |
|
||||||
|
| ``ansible_port`` | no | | Specifies the port used to build the connection to the remote device; if value is unspecified, the ANSIBLE_REMOTE_PORT option is used; it defaults to 22 |
|
||||||
|
| ``ansible_ssh_user`` | no | | Specifies the username that authenticates the CLI login for the connection to the remote device; if value is unspecified, the ANSIBLE_REMOTE_USER environment variable value is used |
|
||||||
|
| ``ansible_ssh_pass`` | no | | Specifies the password that authenticates the connection to the remote device. |
|
||||||
|
| ``ansible_become`` | no | yes, no\* | Instructs the module to enter privileged mode on the remote device before sending any commands; if value is unspecified, the ANSIBLE_BECOME environment variable value is used, and the device attempts to execute all commands in non-privileged mode |
|
||||||
|
| ``ansible_become_method`` | no | enable, sudo\* | Instructs the module to allow the become method to be specified for handling privilege escalation; if value is unspecified, the ANSIBLE_BECOME_METHOD environment variable value is used. |
|
||||||
|
| ``ansible_become_pass`` | no | | Specifies the password to use if required to enter privileged mode on the remote device; if ``ansible_become`` is set to no this key is not applicable. |
|
||||||
|
| ``ansible_network_os`` | yes | os9, null\* | This value is used to load the correct terminal and cliconf plugins to communicate with the remote device. |
|
||||||
|
|
||||||
|
> **NOTE**: Asterisk (*) denotes the default value if none is specified.
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
|
The *os9_aaa* role is built on modules included in the core Ansible code. These modules were added in Ansible version 2.2.0.
|
||||||
|
|
||||||
|
Example playbook
|
||||||
|
----------------
|
||||||
|
|
||||||
|
This example uses the *os9_aaa* role to configure AAA for radius and TACACS servers. It creates a *hosts* file with the switch details and corresponding variables. The hosts file should define the *ansible_network_os* variable with the corresponding Dell EMC Networking OS name.
|
||||||
|
|
||||||
|
When *os9_cfg_generate* is set to true, the variable generates the configuration commands as a .part file in the *build_dir* path. By default, it is set to false and it writes a simple playbook that only references the *os9_aaa* role.
|
||||||
|
|
||||||
|
**Sample hosts file**
|
||||||
|
|
||||||
|
leaf1 ansible_host= <ip_address>
|
||||||
|
|
||||||
|
**Sample host_vars/leaf1**
|
||||||
|
|
||||||
|
hostname: leaf1
|
||||||
|
ansible_become: yes
|
||||||
|
ansible_become_method: xxxxx
|
||||||
|
ansible_become_pass: xxxxx
|
||||||
|
ansible_ssh_user: xxxxx
|
||||||
|
ansible_ssh_pass: xxxxx
|
||||||
|
ansible_network_os: dellemc.os9.os9
|
||||||
|
build_dir: ../temp/os9
|
||||||
|
|
||||||
|
os9_aaa:
|
||||||
|
radius_server:
|
||||||
|
key: radius
|
||||||
|
retransmit: 5
|
||||||
|
timeout: 40
|
||||||
|
deadtime: 2300
|
||||||
|
group:
|
||||||
|
- name: RADIUS
|
||||||
|
host:
|
||||||
|
- ip: 2001:4898:f0:f09b::1002
|
||||||
|
key: 0
|
||||||
|
key_string: aaaa
|
||||||
|
retransmit: 5
|
||||||
|
auth_port: 3
|
||||||
|
timeout: 2
|
||||||
|
state: present
|
||||||
|
vrf:
|
||||||
|
vrf_name: test
|
||||||
|
source_intf: fortyGigE 1/2
|
||||||
|
state: absent
|
||||||
|
state: present
|
||||||
|
host:
|
||||||
|
- ip: 2001:4898:f0:f09b::1002
|
||||||
|
key: xxx
|
||||||
|
retransmit: 5
|
||||||
|
auth_port: 3
|
||||||
|
timeout: 2
|
||||||
|
state: present
|
||||||
|
tacacs_server:
|
||||||
|
key: 7
|
||||||
|
key_string: 9ea8ec421c2e2e5bec757f44205015f6d81e83a4f0aa52fa
|
||||||
|
group:
|
||||||
|
- name: TACACS
|
||||||
|
host:
|
||||||
|
- ip: 2001:4898:f0:f09b::1000
|
||||||
|
key: 0
|
||||||
|
key_string: aaa
|
||||||
|
retransmit: 6
|
||||||
|
auth_port: 3
|
||||||
|
timeout: 2
|
||||||
|
state: present
|
||||||
|
vrf:
|
||||||
|
vrf_name: tes
|
||||||
|
source_intf: fortyGigE 1/3
|
||||||
|
state: present
|
||||||
|
state: present
|
||||||
|
host:
|
||||||
|
- ip: 2001:4898:f0:f09b::1000
|
||||||
|
key: 0
|
||||||
|
key_string: aa
|
||||||
|
retransmit: 5
|
||||||
|
auth_port: 3
|
||||||
|
timeout: 2
|
||||||
|
state: present
|
||||||
|
aaa_accounting:
|
||||||
|
commands:
|
||||||
|
- enable_level: 2
|
||||||
|
accounting_list_name: aa
|
||||||
|
record_option: start-stop
|
||||||
|
state: present
|
||||||
|
- role_name: netadmin
|
||||||
|
accounting_list_name: aa
|
||||||
|
no_accounting: none
|
||||||
|
suppress: True
|
||||||
|
exec:
|
||||||
|
- accounting_list_name: aaa
|
||||||
|
no_accounting: true
|
||||||
|
state: present
|
||||||
|
dot1x: none
|
||||||
|
rest: none
|
||||||
|
aaa_authorization:
|
||||||
|
commands:
|
||||||
|
- enable_level: 2
|
||||||
|
authorization_list_name: aa
|
||||||
|
use_data: local
|
||||||
|
state: present
|
||||||
|
- role_name: netadmin
|
||||||
|
authorization_list_name: aa
|
||||||
|
authorization_method: none
|
||||||
|
use_data: local
|
||||||
|
config_commands: True
|
||||||
|
role_only:
|
||||||
|
exec:
|
||||||
|
- authorization_list_name: aaa
|
||||||
|
authorization_method: if-authenticated
|
||||||
|
use_data: local
|
||||||
|
state: present
|
||||||
|
aaa_authentication:
|
||||||
|
auth_list:
|
||||||
|
- name: default
|
||||||
|
login_or_enable: login
|
||||||
|
server: radius
|
||||||
|
use_password: local
|
||||||
|
state: present
|
||||||
|
- name: console
|
||||||
|
server: tacacs+
|
||||||
|
login_or_enable: login
|
||||||
|
use_password: local
|
||||||
|
aaa_radius:
|
||||||
|
group: RADIUS
|
||||||
|
auth_method: pap
|
||||||
|
aaa_tacacs:
|
||||||
|
group: TACACS
|
||||||
|
line_terminal:
|
||||||
|
vty 0:
|
||||||
|
authorization:
|
||||||
|
commands:
|
||||||
|
- enable_level: 2
|
||||||
|
authorization_list_name: aa
|
||||||
|
state: present
|
||||||
|
- role_name: netadmin
|
||||||
|
authorization_list_name: aa
|
||||||
|
state: present
|
||||||
|
exec:
|
||||||
|
- authorization_list_name: aa
|
||||||
|
state: present
|
||||||
|
accounting:
|
||||||
|
commands:
|
||||||
|
- enable_level: 2
|
||||||
|
accounting_list_name: aa
|
||||||
|
state: present
|
||||||
|
- role_name: netadmin
|
||||||
|
accounting_list_name: aa
|
||||||
|
state: absent
|
||||||
|
exec:
|
||||||
|
accounting_list_name: aa
|
||||||
|
state: present
|
||||||
|
authentication:
|
||||||
|
enable:
|
||||||
|
login: console
|
||||||
|
|
||||||
|
**Simple playbook to setup system - leaf.yaml**
|
||||||
|
|
||||||
|
- hosts: leaf1
|
||||||
|
roles:
|
||||||
|
- dellemc.os9.os9_aaa
|
||||||
|
|
||||||
|
**Run**
|
||||||
|
|
||||||
|
ansible-playbook -i hosts leaf.yaml
|
||||||
|
|
||||||
|
(c) 2017-2020 Dell Inc. or its subsidiaries. All Rights Reserved.
|
16
roles/os9_aaa/defaults/main.yml
Normal file
16
roles/os9_aaa/defaults/main.yml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
# defaults file for dellemc.os9.os9_aaa
|
||||||
|
attribute_type:
|
||||||
|
mandatory: mandatory
|
||||||
|
on_for_login_auth: on-for-login-auth
|
||||||
|
include_in_access_req: include-in-access-req
|
||||||
|
mac: "mac format"
|
||||||
|
mac_ietf: "mac format ietf"
|
||||||
|
mac_ietf_lower_case: "mac format ietf lower-case"
|
||||||
|
mac_ietf_upper_case: "mac format ietf upper-case"
|
||||||
|
mac_legacy: "mac format legacy"
|
||||||
|
mac_legacy_lower_case: "mac format legacy lower-case"
|
||||||
|
mac_legacy_upper_case: "mac format legacy upper-case"
|
||||||
|
mac_unformatted: "mac format unformatted"
|
||||||
|
mac_unformatted_lower_case: "mac format unformatted lower-case"
|
||||||
|
mac_unformatted_upper_case: "mac format unformatted upper-case"
|
2
roles/os9_aaa/handlers/main.yml
Normal file
2
roles/os9_aaa/handlers/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
# handlers file for dellemc.os9.os9_aaa
|
17
roles/os9_aaa/meta/main.yml
Normal file
17
roles/os9_aaa/meta/main.yml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# copyright (c) 2017-2020 Dell Inc. or its subsidiaries. All Rights Reserved.
|
||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Dell EMC Networking Engineering
|
||||||
|
description: The os9_aaa role facilitates the configuration of Authentication Authorization Acccounting (AAA) attributes in devices running Dell EMC Networking Operating Systems.
|
||||||
|
license: Apache 2.0
|
||||||
|
min_ansible_version: 2.2
|
||||||
|
|
||||||
|
platforms:
|
||||||
|
- name: os9
|
||||||
|
|
||||||
|
galaxy_tags:
|
||||||
|
- networking
|
||||||
|
- dell
|
||||||
|
- emc
|
||||||
|
- dellemc
|
||||||
|
- os9
|
17
roles/os9_aaa/tasks/main.yml
Normal file
17
roles/os9_aaa/tasks/main.yml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
# tasks file for os9
|
||||||
|
|
||||||
|
- name: "Generating AAA configuration for os9"
|
||||||
|
template:
|
||||||
|
src: os9_aaa.j2
|
||||||
|
dest: "{{ build_dir }}/aaa9_{{ hostname }}.conf.part"
|
||||||
|
when: (ansible_network_os is defined and ansible_network_os == "dellemc.os9.os9") and ((os9_cfg_generate | default('False')) | bool)
|
||||||
|
# notify: save config os9
|
||||||
|
register: generate_output
|
||||||
|
|
||||||
|
- name: "Provisioning AAA configuration for os9"
|
||||||
|
os9_config:
|
||||||
|
src: os9_aaa.j2
|
||||||
|
when: (ansible_network_os is defined and ansible_network_os == "dellemc.os9.os9")
|
||||||
|
# notify: save config os9
|
||||||
|
register: output
|
680
roles/os9_aaa/templates/os9_aaa.j2
Normal file
680
roles/os9_aaa/templates/os9_aaa.j2
Normal file
|
@ -0,0 +1,680 @@
|
||||||
|
#jinja2: trim_blocks: True,lstrip_blocks: True
|
||||||
|
{#############################################
|
||||||
|
Purpose:
|
||||||
|
Configure AAA commands for os9 Devices
|
||||||
|
os9_aaa:
|
||||||
|
tacacs_server:
|
||||||
|
key: 7
|
||||||
|
key_string: 9ea8ec421c2e2e5bec757f44205015f6d81e83a4f0aa52fa
|
||||||
|
group:
|
||||||
|
- name: TACACS
|
||||||
|
host:
|
||||||
|
- ip: 2001:4898:f0:f09b::1000
|
||||||
|
key: 0
|
||||||
|
key_string: aaa
|
||||||
|
auth_port: 3
|
||||||
|
timeout: 2
|
||||||
|
state: present
|
||||||
|
vrf:
|
||||||
|
vrf_name: test
|
||||||
|
source_intf: fortyGigE 1/2
|
||||||
|
state: present
|
||||||
|
state: present
|
||||||
|
host:
|
||||||
|
- ip: 2001:4898:f0:f09b::1000
|
||||||
|
key: 0
|
||||||
|
key_string: aaa
|
||||||
|
auth_port: 3
|
||||||
|
timeout: 2
|
||||||
|
state: present
|
||||||
|
radius_server:
|
||||||
|
key: 7
|
||||||
|
key_string: 9ea8ec421c2e2e5bec757f44205015f6d81e83a4f0aa52fb
|
||||||
|
retransmit: 5
|
||||||
|
timeout: 10
|
||||||
|
deadtime: 2000
|
||||||
|
group:
|
||||||
|
- name: Radius
|
||||||
|
host:
|
||||||
|
- ip: 2001:4898:f0:f09b::1001
|
||||||
|
key: 0
|
||||||
|
key_string: aaa
|
||||||
|
retransmit: 5
|
||||||
|
auth_port: 3
|
||||||
|
timeout: 2
|
||||||
|
state: present
|
||||||
|
vrf:
|
||||||
|
vrf_name: test
|
||||||
|
source_intf: fortyGigE 1/3
|
||||||
|
state: present
|
||||||
|
state: present
|
||||||
|
host:
|
||||||
|
- ip: 2001:4898:f0:f09b::1001
|
||||||
|
key: 0
|
||||||
|
key_string: aaa
|
||||||
|
retransmit: 5
|
||||||
|
auth_port: 3
|
||||||
|
timeout: 2
|
||||||
|
state: present
|
||||||
|
aaa_accounting:
|
||||||
|
commands:
|
||||||
|
- enable_level: 2
|
||||||
|
accounting_list_name: aa
|
||||||
|
no_accounting: true
|
||||||
|
record_option: start-stop
|
||||||
|
state: present
|
||||||
|
suppress: True
|
||||||
|
exec:
|
||||||
|
- accounting_list_name: aaa
|
||||||
|
no_accounting: true
|
||||||
|
state: present
|
||||||
|
dot1x: none
|
||||||
|
rest: none
|
||||||
|
aaa_authorization:
|
||||||
|
commands:
|
||||||
|
- enable_level: 2
|
||||||
|
authorization_list_name: aa
|
||||||
|
use_data: local
|
||||||
|
state: present
|
||||||
|
- role_name: netadmin
|
||||||
|
authorization_list_name: aa
|
||||||
|
authorization_method: none
|
||||||
|
use_data: local
|
||||||
|
config_commands: True
|
||||||
|
role_only: True
|
||||||
|
exec:
|
||||||
|
- authorization_list_name: aaa
|
||||||
|
authorization_method: if-authenticated
|
||||||
|
use_data: local
|
||||||
|
state: present
|
||||||
|
aaa_radius:
|
||||||
|
group: RADIUS
|
||||||
|
auth_method: pap
|
||||||
|
aaa_tacacs:
|
||||||
|
group: TACACS
|
||||||
|
aaa_authentication:
|
||||||
|
auth_list:
|
||||||
|
- name: default
|
||||||
|
login_or_enable: login
|
||||||
|
server: tacacs+
|
||||||
|
use_password: local
|
||||||
|
state: present
|
||||||
|
- name: console
|
||||||
|
server: radius
|
||||||
|
login_or_enable: login
|
||||||
|
use_password: local
|
||||||
|
line_terminal:
|
||||||
|
vty 0:
|
||||||
|
authorization:
|
||||||
|
commands:
|
||||||
|
- enable_level: 2
|
||||||
|
authorization_list_name: aa
|
||||||
|
state: present
|
||||||
|
- enable_level: 2
|
||||||
|
authorization_list_name: aa
|
||||||
|
state: present
|
||||||
|
exec:
|
||||||
|
- authorization_list_name: aa
|
||||||
|
state: present
|
||||||
|
accounting:
|
||||||
|
commands:
|
||||||
|
- enable_level: 2
|
||||||
|
accounting_list_name: aa
|
||||||
|
state: present
|
||||||
|
- enable_level: 2
|
||||||
|
accounting_list_name: aa
|
||||||
|
state: present
|
||||||
|
exec:
|
||||||
|
- accounting_list_name: aa
|
||||||
|
state: present
|
||||||
|
authentication:
|
||||||
|
enable: aa
|
||||||
|
login: console
|
||||||
|
##################################################}
|
||||||
|
{% if os9_aaa is defined and os9_aaa %}
|
||||||
|
{% for key in os9_aaa.keys() %}
|
||||||
|
{% set aaa_vars = os9_aaa[key] %}
|
||||||
|
{% if key == "tacacs_server" %}
|
||||||
|
{% set server = "tacacs-server" %}
|
||||||
|
{% endif %}
|
||||||
|
{% if key == "radius_server" %}
|
||||||
|
{% set server = "radius-server" %}
|
||||||
|
{% endif %}
|
||||||
|
{% if server is defined and server %}
|
||||||
|
{% if aaa_vars %}
|
||||||
|
{% set item = aaa_vars %}
|
||||||
|
{% if item.retransmit is defined %}
|
||||||
|
{% if item.retransmit %}
|
||||||
|
{{ server }} retransmit {{ item.retransmit }}
|
||||||
|
{% else %}
|
||||||
|
no {{ server }} retransmit
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if item.timeout is defined %}
|
||||||
|
{% if item.timeout %}
|
||||||
|
{{ server }} timeout {{ item.timeout }}
|
||||||
|
{% else %}
|
||||||
|
no {{ server }} timeout
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if item.deadtime is defined %}
|
||||||
|
{% if item.deadtime %}
|
||||||
|
{{ server }} deadtime {{ item.deadtime }}
|
||||||
|
{% else %}
|
||||||
|
no {{ server }} deadtime
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if item.key is defined %}
|
||||||
|
{% if item.key == 0 or item.key == 7 %}
|
||||||
|
{% if item.key_string is defined and item.key_string%}
|
||||||
|
{{ server }} key {{ item.key }} {{ item.key_string }}
|
||||||
|
{% endif %}
|
||||||
|
{% elif item.key %}
|
||||||
|
{{ server }} key {{ item.key }}
|
||||||
|
{% else %}
|
||||||
|
no {{ server }} key
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if item.host is defined and item.host %}
|
||||||
|
{% for hostlist in item.host %}
|
||||||
|
{% if hostlist.ip is defined and hostlist.ip %}
|
||||||
|
{% if hostlist.state is defined and hostlist.state == "absent" %}
|
||||||
|
{% if (hostlist.key is defined and (hostlist.key == 0 or hostlist.key == 7) ) and (hostlist.key_string is defined and hostlist.key_string) and (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) and (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server" %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.key is defined and (hostlist.key == 0 or hostlist.key == 7)) and (hostlist.key_string is defined and hostlist.key_string) and (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }}
|
||||||
|
{% elif (hostlist.key is defined and (hostlist.key == 0 or hostlist.key == 7)) and (hostlist.key_string is defined and hostlist.key_string) and (hostlist.timeout is defined and hostlist.timeout) %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }} timeout {{ hostlist.timeout }}
|
||||||
|
{% elif (hostlist.key is defined and (hostlist.key == 0 or hostlist.key == 7)) and (hostlist.key_string is defined and hostlist.key_string) %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }}
|
||||||
|
{% elif (hostlist.key is defined and hostlist.key) and (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) and (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server" %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.key is defined and hostlist.key) and (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }}
|
||||||
|
{% elif (hostlist.key is defined and hostlist.key) and (hostlist.timeout is defined and hostlist.timeout) %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} timeout {{ hostlist.timeout }}
|
||||||
|
{% elif (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) and (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server" %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }}
|
||||||
|
{% elif (hostlist.auth_port is defined and hostlist.auth_port) and (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server" %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} {{ port }} {{ hostlist.auth_port }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.timeout is defined and hostlist.timeout) %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} timeout {{ hostlist.timeout }}
|
||||||
|
{% elif (hostlist.auth_port is defined and hostlist.auth_port) %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} {{ port }} {{ hostlist.auth_port }}
|
||||||
|
{% elif (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server" %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.key is defined and (hostlist.key == 0 or hostlist.key == 7) )%}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }}
|
||||||
|
{% elif (hostlist.key is defined and hostlist.key) %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} key {{ hostlist.key }}
|
||||||
|
{% else %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if (hostlist.key is defined and (hostlist.key == 0 or hostlist.key == 7)) and (hostlist.key_string is defined and hostlist.key_string) and (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) and (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server" %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.key is defined and (hostlist.key== 0 or hostlist.key == 7)) and (hostlist.key_string is defined and hostlist.key_string) and (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }}
|
||||||
|
{% elif (hostlist.key is defined and (hostlist.key == 0 or hostlist.key == 7)) and (hostlist.key_string is defined and hostlist.key_string) and (hostlist.timeout is defined and hostlist.timeout) %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }} timeout {{ hostlist.timeout }}
|
||||||
|
{% elif (hostlist.key is defined and (hostlist.key == 0 or hostlist.key == 7)) and (hostlist.key_string is defined and hostlist.key_string) %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }}
|
||||||
|
{% elif (hostlist.key is defined and hostlist.key) and (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) and (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server" %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.key is defined and hostlist.key) and (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }}
|
||||||
|
{% elif (hostlist.key is defined and hostlist.key) and (hostlist.timeout is defined and hostlist.timeout) %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} timeout {{ hostlist.timeout }}
|
||||||
|
{% elif (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) and (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server" %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }}
|
||||||
|
{% elif (hostlist.auth_port is defined and hostlist.auth_port) and (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server" %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} {{ port }} {{ hostlist.auth_port }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.timeout is defined and hostlist.timeout) %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} timeout {{ hostlist.timeout }}
|
||||||
|
{% elif (hostlist.auth_port is defined and hostlist.auth_port) %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} {{ port }} {{ hostlist.auth_port }}
|
||||||
|
{% elif (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server"%}
|
||||||
|
{{ server }} host {{ hostlist.ip }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.key is defined and (hostlist.key == 0 or hostlist.key == 7))%}
|
||||||
|
{{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }}
|
||||||
|
{% elif (hostlist.key is defined and hostlist.key) %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} key {{ hostlist.key }}
|
||||||
|
{% else %}
|
||||||
|
{{ server }} host {{ hostlist.ip }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if item.group is defined and item.group %}
|
||||||
|
{% for groupitem in item.group %}
|
||||||
|
{% if groupitem.name is defined and groupitem.name %}
|
||||||
|
{% if groupitem.state is defined and groupitem.state == "absent" %}
|
||||||
|
no {{ server }} group {{ groupitem.name }}
|
||||||
|
{% else %}
|
||||||
|
{{ server }} group {{ groupitem.name }}
|
||||||
|
{% if groupitem.host is defined and groupitem.host %}
|
||||||
|
{% for hostlist in groupitem.host %}
|
||||||
|
{% if hostlist.ip is defined and hostlist.ip %}
|
||||||
|
{% if hostlist.state is defined and hostlist.state == "absent" %}
|
||||||
|
{% if (hostlist.key is defined and (hostlist.key or hostlist.key == 7)) and (hostlist.key_string is defined and hostlist.key_string) and (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) and (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server" %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.key is defined and (hostlist.key or hostlist.key == 7)) and (hostlist.key_string is defined and hostlist.key_string) and (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }}
|
||||||
|
{% elif (hostlist.key is defined and (hostlist.key or hostlist.key == 7)) and (hostlist.key_string is defined and hostlist.key_string) and (hostlist.timeout is defined and hostlist.timeout) %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }} timeout {{ hostlist.timeout }}
|
||||||
|
{% elif (hostlist.key is defined and (hostlist.key or hostlist.key == 7)) and (hostlist.key_string is defined and hostlist.key_string) %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }}
|
||||||
|
{% elif (hostlist.key is defined and hostlist.key) and (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) and (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server" %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.key is defined and hostlist.key) and (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }}
|
||||||
|
{% elif (hostlist.key is defined and hostlist.key) and (hostlist.timeout is defined and hostlist.timeout) %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} timeout {{ hostlist.timeout }}
|
||||||
|
{% elif (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) and (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server" %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }}
|
||||||
|
{% elif (hostlist.auth_port is defined and hostlist.auth_port) and (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server" %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} {{ port }} {{ hostlist.auth_port }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.timeout is defined and hostlist.timeout) %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} timeout {{ hostlist.timeout }}
|
||||||
|
{% elif (hostlist.auth_port is defined and hostlist.auth_port) %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} {{ port }} {{ hostlist.auth_port }}
|
||||||
|
{% elif (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server" %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.key is defined and (hostlist.key == 0 or hostlist.key == 7)) %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }}
|
||||||
|
{% elif (hostlist.key is defined and hostlist.key) %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }} key {{ hostlist.key }}
|
||||||
|
{% else %}
|
||||||
|
no {{ server }} host {{ hostlist.ip }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if (hostlist.key is defined and (hostlist.key== 0 or hostlist.key == 7)) and (hostlist.key_string is defined and hostlist.key_string) and (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) and (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server" %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.key is defined and (hostlist.key == 0 or hostlist.key == 7)) and (hostlist.key_string is defined and hostlist.key_string) and (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }}
|
||||||
|
{% elif (hostlist.key is defined and (hostlist.key == 0 or hostlist.key == 7)) and (hostlist.key_string is defined and hostlist.key_string) and (hostlist.timeout is defined and hostlist.timeout) %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }} timeout {{ hostlist.timeout }}
|
||||||
|
{% elif (hostlist.key is defined and (hostlist.key == 0 or hostlist.key == 7)) and (hostlist.key_string is defined and hostlist.key_string) %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }}
|
||||||
|
{% elif (hostlist.key is defined and hostlist.key) and (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) and (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server" %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.key is defined and hostlist.key) and (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }}
|
||||||
|
{% elif (hostlist.key is defined and hostlist.key) and (hostlist.timeout is defined and hostlist.timeout) %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} timeout {{ hostlist.timeout }}
|
||||||
|
{% elif (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) and (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server" %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.timeout is defined and hostlist.timeout) and (hostlist.auth_port is defined and hostlist.auth_port) %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} timeout {{ hostlist.timeout }} {{ port }} {{ hostlist.auth_port }}
|
||||||
|
{% elif (hostlist.auth_port is defined and hostlist.auth_port) and (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server" %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} {{ port }} {{ hostlist.auth_port }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.timeout is defined and hostlist.timeout) %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} timeout {{ hostlist.timeout }}
|
||||||
|
{% elif (hostlist.auth_port is defined and hostlist.auth_port) %}
|
||||||
|
{% if server == "radius-server" %}{%set port = "auth-port" %}{%else %}{% set port = "port" %}{% endif %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} {{ port }} {{ hostlist.auth_port }}
|
||||||
|
{% elif (hostlist.retransmit is defined and hostlist.retransmit) and server == "radius-server"%}
|
||||||
|
{{ server }} host {{ hostlist.ip }} retransmit {{ hostlist.retransmit }}
|
||||||
|
{% elif (hostlist.key is defined and (hostlist.key == 0 or hostlist.key == 7)) %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} key {{ hostlist.key }} {{ hostlist.key_string }}
|
||||||
|
{% elif (hostlist.key is defined and hostlist.key) %}
|
||||||
|
{{ server }} host {{ hostlist.ip }} key {{ hostlist.key }}
|
||||||
|
{% else %}
|
||||||
|
{{ server }} host {{ hostlist.ip }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if groupitem.vrf is defined and groupitem.vrf %}
|
||||||
|
{% if groupitem.vrf.vrf_name is defined and groupitem.vrf.vrf_name %}
|
||||||
|
{% if groupitem.vrf.state is defined and groupitem.vrf.state == "absent" %}
|
||||||
|
no {{ server }} vrf {{ groupitem.vrf.vrf_name }}
|
||||||
|
{% else %}
|
||||||
|
{% if groupitem.vrf.source_intf is defined and groupitem.vrf.source_intf %}
|
||||||
|
{{ server }} vrf {{ groupitem.vrf.vrf_name }} source-interface {{ groupitem.vrf.source_intf }}
|
||||||
|
{% else %}
|
||||||
|
{{ server }} vrf {{ groupitem.vrf.vrf_name }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if os9_aaa.aaa_accounting is defined and os9_aaa.aaa_accounting %}
|
||||||
|
{% set aaa_accounting = os9_aaa.aaa_accounting %}
|
||||||
|
{% if aaa_accounting.suppress is defined %}
|
||||||
|
{% if aaa_accounting.suppress %}
|
||||||
|
aaa accounting suppress null-username
|
||||||
|
{% else %}
|
||||||
|
no aaa accounting suppress null-username
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if aaa_accounting.dot1x is defined %}
|
||||||
|
{% if aaa_accounting.dot1x == "none" %}
|
||||||
|
aaa accounting dot1x default none
|
||||||
|
{% elif aaa_accounting.dotx %}
|
||||||
|
aaa accounting dot1x default {{ aaa_accounting.dot1x }} tacacs+
|
||||||
|
{% else %}
|
||||||
|
no aaa accounting dotx default
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if aaa_accounting.rest is defined %}
|
||||||
|
{% if aaa_accounting.rest == "none" %}
|
||||||
|
aaa accounting rest default none
|
||||||
|
{% elif aaa_accounting.rest %}
|
||||||
|
aaa accounting rest default {{ aaa_accounting.rest }} tacacs+
|
||||||
|
{% else %}
|
||||||
|
no aaa accounting rest default
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if aaa_accounting.exec is defined and aaa_accounting.exec %}
|
||||||
|
{% for command in aaa_accounting.exec %}
|
||||||
|
{% if command.accounting_list_name is defined and command.accounting_list_name %}
|
||||||
|
{% if command.state is defined and command.state == "absent" %}
|
||||||
|
no aaa accounting exec {{ command.accounting_list_name }}
|
||||||
|
{% else %}
|
||||||
|
{% if command.record_option is defined and command.record_option %}
|
||||||
|
aaa accounting exec {{ command.accounting_list_name }} {{ command.record_option }} tacacs+
|
||||||
|
{% elif command.no_accounting is defined and command.no_accounting %}
|
||||||
|
aaa accounting exec {{ command.accounting_list_name }} none
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if aaa_accounting.commands is defined and aaa_accounting.commands %}
|
||||||
|
{% for command in aaa_accounting.commands %}
|
||||||
|
{% if command.enable_level is defined and command.enable_level %}
|
||||||
|
{% if command.accounting_list_name is defined and command.accounting_list_name %}
|
||||||
|
{% if command.state is defined and command.state == "absent" %}
|
||||||
|
no aaa accounting commands {{ command.enable_level }} {{ command.accounting_list_name }}
|
||||||
|
{% else %}
|
||||||
|
{% if command.record_option is defined and command.record_option %}
|
||||||
|
aaa accounting commands {{ command.enable_level }} {{ command.accounting_list_name }} {{ command.record_option }} tacacs+
|
||||||
|
{% elif command.no_accounting is defined and command.no_accounting %}
|
||||||
|
aaa accounting commands {{ command.enable_level }} {{ command.accounting_list_name }} none
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% elif command.role_name is defined and command.role_name %}
|
||||||
|
{% if command.accounting_list_name is defined and command.accounting_list_name %}
|
||||||
|
{% if command.state is defined and command.state == "absent" %}
|
||||||
|
no aaa accounting commands role {{ command.role_name }} {{ command.accounting_list_name }}
|
||||||
|
{% else %}
|
||||||
|
{% if command.record_option is defined and command.record_option %}
|
||||||
|
aaa accounting commands role {{ command.role_name }} {{ command.accounting_list_name }} {{ command.record_option }} tacacs+
|
||||||
|
{% elif command.no_accounting is defined and command.no_accounting %}
|
||||||
|
aaa accounting commands role {{ command.role_name }} {{ command.accounting_list_name }} none
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if os9_aaa.aaa_authorization is defined and os9_aaa.aaa_authorization %}
|
||||||
|
{% set aaa_authorization = os9_aaa.aaa_authorization %}
|
||||||
|
{% if aaa_authorization.config_commands is defined %}
|
||||||
|
{% if aaa_authorization.config_commands %}
|
||||||
|
aaa authorization config-commands
|
||||||
|
{% else %}
|
||||||
|
no aaa authorization config-commands
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if aaa_authorization.role_only is defined %}
|
||||||
|
{% if aaa_authorization.role_only %}
|
||||||
|
aaa authorization role-only
|
||||||
|
{% else %}
|
||||||
|
no aaa authorization role-only
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if aaa_authorization.exec is defined and aaa_authorization.exec %}
|
||||||
|
{% for command in aaa_authorization.exec %}
|
||||||
|
{% if command.authorization_list_name is defined and command.authorization_list_name %}
|
||||||
|
{% if command.state is defined and command.state == "absent" %}
|
||||||
|
no aaa authorization exec {{ command.authorization_list_name }}
|
||||||
|
{% else %}
|
||||||
|
{% if command.use_data is defined and command.use_data %}
|
||||||
|
{% if command.authorization_method is defined and command.authorization_method %}
|
||||||
|
aaa authorization exec {{ command.authorization_list_name }} {{ command.use_data }} {{ command.authorization_method }}
|
||||||
|
{% else %}
|
||||||
|
aaa authorization exec {{ command.authorization_list_name }} {{ command.use_data }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if command.authorization_method is defined and command.authorization_method %}
|
||||||
|
aaa authorization exec {{ command.authorization_list_name }} {{ command.authorization_method }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if aaa_authorization.commands is defined and aaa_authorization.commands %}
|
||||||
|
{% for command in aaa_authorization.commands %}
|
||||||
|
{% if command.enable_level is defined and command.enable_level %}
|
||||||
|
{% if command.authorization_list_name is defined and command.authorization_list_name %}
|
||||||
|
{% if command.state is defined and command.state == "absent" %}
|
||||||
|
no aaa authorization commands {{ command.enable_level }} {{ command.authorization_list_name }}
|
||||||
|
{% else %}
|
||||||
|
{% if command.use_data is defined and command.use_data %}
|
||||||
|
{% if command.authorization_method is defined and command.authorization_method %}
|
||||||
|
aaa authorization commands {{ command.enable_level }} {{ command.authorization_list_name }} {{ command.use_data }} {{ command.authorization_method }}
|
||||||
|
{% else %}
|
||||||
|
aaa authorization commands {{ command.enable_level }} {{ command.authorization_list_name }} {{ command.use_data }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if command.authorization_method is defined and command.authorization_method %}
|
||||||
|
aaa authorization commands {{ command.enable_level }} {{ command.authorization_list_name }} {{ command.authorization_method }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% elif command.role_name is defined and command.role_name %}
|
||||||
|
{% if command.authorization_list_name is defined and command.authorization_list_name %}
|
||||||
|
{% if command.state is defined and command.state == "absent" %}
|
||||||
|
no aaa authorization commands role {{ command.role_name }} {{ command.authorization_list_name }}
|
||||||
|
{% else %}
|
||||||
|
{% if command.use_data is defined and command.use_data %}
|
||||||
|
{% if command.authorization_method is defined and command.authorization_method %}
|
||||||
|
aaa authorization commands role {{ command.role_name }} {{ command.authorization_list_name }} {{ command.use_data }} {{ command.authorization_method }}
|
||||||
|
{% else %}
|
||||||
|
aaa authorization commands role {{ command.role_name }} {{ command.authorization_list_name }} {{ command.use_data }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if command.authorization_method is defined and command.authorization_method %}
|
||||||
|
aaa authorization commands role {{ command.role_name }} {{ command.authorization_list_name }} {{ command.authorization_method }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if os9_aaa.aaa_radius is defined and os9_aaa.aaa_radius %}
|
||||||
|
{% if os9_aaa.aaa_radius.group is defined %}
|
||||||
|
{% if os9_aaa.aaa_radius.group %}
|
||||||
|
aaa radius group {{ os9_aaa.aaa_radius.group }}
|
||||||
|
{% else %}
|
||||||
|
no aaa radius group
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if os9_aaa.aaa_radius.auth_method is defined %}
|
||||||
|
{% if os9_aaa.aaa_radius.auth_method %}
|
||||||
|
aaa radius auth-method {{ os9_aaa.aaa_radius.auth_method }}
|
||||||
|
{% else %}
|
||||||
|
no aaa radius auth-method
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if os9_aaa.aaa_tacacs is defined and os9_aaa.aaa_tacacs %}
|
||||||
|
{% if os9_aaa.aaa_tacacs.group is defined %}
|
||||||
|
{% if os9_aaa.aaa_tacacs.group %}
|
||||||
|
aaa tacacs group {{ os9_aaa.aaa_tacacs.group }}
|
||||||
|
{% else %}
|
||||||
|
no aaa tacacs group
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if os9_aaa.aaa_authentication is defined and os9_aaa.aaa_authentication %}
|
||||||
|
{% if os9_aaa.aaa_authentication.auth_list is defined and os9_aaa.aaa_authentication.auth_list %}
|
||||||
|
{% for auth_list in os9_aaa.aaa_authentication.auth_list %}
|
||||||
|
{% if auth_list.login_or_enable is defined and auth_list.login_or_enable %}
|
||||||
|
{% if auth_list.name is defined and auth_list.name %}
|
||||||
|
{% if auth_list.state is defined and auth_list.state == "absent" %}
|
||||||
|
no aaa authentication {{ auth_list.login_or_enable }} {{ auth_list.name }}
|
||||||
|
{% else %}
|
||||||
|
{% if auth_list.server is defined and auth_list.server %}
|
||||||
|
{% if auth_list.use_password is defined and auth_list.use_password %}
|
||||||
|
aaa authentication {{ auth_list.login_or_enable }} {{ auth_list.name }} {{ auth_list.server }} {{ auth_list.use_password }}
|
||||||
|
{% else %}
|
||||||
|
aaa authentication {{ auth_list.login_or_enable }} {{ auth_list.name }} {{ auth_list.server }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if auth_list.use_password is defined and auth_list.use_password %}
|
||||||
|
aaa authentication {{ auth_list.login_or_enable }} {{ auth_list.name }} {{ auth_list.use_password }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if os9_aaa.line_terminal is defined and os9_aaa.line_terminal %}
|
||||||
|
{% for terminal in os9_aaa.line_terminal.keys() %}
|
||||||
|
{% set terminal_vars = os9_aaa.line_terminal[terminal] %}
|
||||||
|
line {{ terminal }}
|
||||||
|
{% if terminal_vars.authorization is defined and terminal_vars.authorization %}
|
||||||
|
{% if terminal_vars.authorization.commands is defined and terminal_vars.authorization.commands %}
|
||||||
|
{% for commands in terminal_vars.authorization.commands %}
|
||||||
|
{% if commands.enable_level is defined and commands.enable_level %}
|
||||||
|
{% if commands.state is defined and commands.state == "absent" %}
|
||||||
|
no authorization commands {{ commands.enable_level }}
|
||||||
|
{% else %}
|
||||||
|
{% if commands.authorization_list_name is defined and commands.authorization_list_name %}
|
||||||
|
authorization commands {{ commands.enable_level }} {{ commands.authorization_list_name }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% elif commands.role_name is defined and commands.role_name %}
|
||||||
|
{% if commands.state is defined and commands.state == "absent" %}
|
||||||
|
no authorization commands role {{ commands.role_name }}
|
||||||
|
{% else %}
|
||||||
|
{% if commands.authorization_list_name is defined and commands.authorization_list_name %}
|
||||||
|
authorization commands role {{ commands.role_name }} {{ commands.authorization_list_name }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if terminal_vars.authorization.exec is defined and terminal_vars.authorization.exec %}
|
||||||
|
{% set exec = terminal_vars.authorization.exec %}
|
||||||
|
{% if exec.state is defined and exec.state == "absent" %}
|
||||||
|
no authorization exec
|
||||||
|
{% else %}
|
||||||
|
{% if exec.authorization_list_name is defined and exec.authorization_list_name %}
|
||||||
|
authorization exec {{ exec.authorization_list_name }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if terminal_vars.accounting is defined and terminal_vars.accounting %}
|
||||||
|
{% if terminal_vars.accounting.commands is defined and terminal_vars.accounting.commands %}
|
||||||
|
{% for commands in terminal_vars.accounting.commands %}
|
||||||
|
{% if commands.enable_level is defined and commands.enable_level %}
|
||||||
|
{% if commands.state is defined and commands.state == "absent" %}
|
||||||
|
no accounting commands {{ commands.enable_level }}
|
||||||
|
{% else %}
|
||||||
|
{% if commands.accounting_list_name is defined and commands.accounting_list_name %}
|
||||||
|
accounting commands {{ commands.enable_level }} {{ commands.accounting_list_name }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% elif commands.role_name is defined and commands.role_name %}
|
||||||
|
{% if commands.state is defined and commands.state == "absent" %}
|
||||||
|
no accounting commands role {{ commands.role_name }}
|
||||||
|
{% else %}
|
||||||
|
{% if commands.accounting_list_name is defined and commands.accounting_list_name %}
|
||||||
|
accounting commands role {{ commands.role_name }} {{ commands.accounting_list_name }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if terminal_vars.accounting.exec is defined and terminal_vars.accounting.exec %}
|
||||||
|
{% set exec = terminal_vars.accounting.exec %}
|
||||||
|
{% if exec.state is defined and exec.state == "absent" %}
|
||||||
|
no accounting exec
|
||||||
|
{% else %}
|
||||||
|
{% if exec.accounting_list_name is defined and exec.accounting_list_name %}
|
||||||
|
authorization exec {{ exec.accounting_list_name }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if terminal_vars.authentication is defined and terminal_vars.authentication %}
|
||||||
|
{% if terminal_vars.authentication.enable is defined %}
|
||||||
|
{% if terminal_vars.authentication.enable %}
|
||||||
|
enable authentication {{ terminal_vars.authentication.enable }}
|
||||||
|
{% else %}
|
||||||
|
no enable authentication
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if terminal_vars.authentication.login is defined %}
|
||||||
|
{% if terminal_vars.authentication.login %}
|
||||||
|
login authentication {{ terminal_vars.authentication.login }}
|
||||||
|
{% else %}
|
||||||
|
no login authentication
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
20
roles/os9_aaa/tests/inventory.yaml
Normal file
20
roles/os9_aaa/tests/inventory.yaml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
spine1 ansible_host=100.94.210.44
|
||||||
|
spine2 ansible_host=10.11.182.26
|
||||||
|
leaf1 ansible_host=10.11.182.27
|
||||||
|
leaf2 ansible_host=10.11.182.28
|
||||||
|
leaf3 ansible_host=10.11.182.29
|
||||||
|
leaf4 ansible_host=10.11.182.30
|
||||||
|
|
||||||
|
[spine]
|
||||||
|
spine1
|
||||||
|
spine2
|
||||||
|
|
||||||
|
[leaf]
|
||||||
|
leaf1
|
||||||
|
leaf2
|
||||||
|
leaf3
|
||||||
|
leaf4
|
||||||
|
|
||||||
|
[datacenter:children]
|
||||||
|
spine
|
||||||
|
leaf
|
133
roles/os9_aaa/tests/main.os6.yaml
Normal file
133
roles/os9_aaa/tests/main.os6.yaml
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
---
|
||||||
|
# vars file for dellemc.os9.os9_aaa,
|
||||||
|
# below gives a sample configuration
|
||||||
|
# Sample variables for OS9 device
|
||||||
|
os9_aaa:
|
||||||
|
radius_server:
|
||||||
|
key: radius
|
||||||
|
retransmit: 5
|
||||||
|
timeout: 40
|
||||||
|
deadtime: 2300
|
||||||
|
group:
|
||||||
|
- name: RADIUS
|
||||||
|
host:
|
||||||
|
- ip: 2001:4898:f0:f09b::1002
|
||||||
|
key: 0
|
||||||
|
key_string: aaaa
|
||||||
|
retransmit: 5
|
||||||
|
auth_port: 3
|
||||||
|
timeout: 2
|
||||||
|
state: present
|
||||||
|
vrf:
|
||||||
|
vrf_name: test
|
||||||
|
source_intf: fortyGigE 1/2
|
||||||
|
state: absent
|
||||||
|
state: present
|
||||||
|
host:
|
||||||
|
- ip: 10.1.1.1
|
||||||
|
key: 0
|
||||||
|
key_string: aaa
|
||||||
|
retransmit: 6
|
||||||
|
auth_port: 3
|
||||||
|
timeout: 2
|
||||||
|
state: present
|
||||||
|
tacacs_server:
|
||||||
|
key: 7
|
||||||
|
key_string: 9ea8ec421c2e2e5bec757f44205015f6d81e83a4f0aa52fa
|
||||||
|
group:
|
||||||
|
- name: TACACS
|
||||||
|
host:
|
||||||
|
- ip: 2001:4898:f0:f09b::1000
|
||||||
|
key: 0
|
||||||
|
key_string: aaa
|
||||||
|
auth_port: 3
|
||||||
|
timeout: 2
|
||||||
|
state: present
|
||||||
|
vrf:
|
||||||
|
vrf_name: tes
|
||||||
|
source_intf: fortyGigE 1/3
|
||||||
|
state: present
|
||||||
|
state: present
|
||||||
|
host:
|
||||||
|
- ip: 2001:4898:f0:f09b::1000
|
||||||
|
key: 0
|
||||||
|
key_string: aaa
|
||||||
|
auth_port: 3
|
||||||
|
timeout: 2
|
||||||
|
state: present
|
||||||
|
aaa_accounting:
|
||||||
|
commands:
|
||||||
|
- enable_level: 2
|
||||||
|
accounting_list_name: aa
|
||||||
|
record_option: start-stop
|
||||||
|
state: present
|
||||||
|
- role_name: netadmin
|
||||||
|
accounting_list_name: aa
|
||||||
|
no_accounting: none
|
||||||
|
suppress: True
|
||||||
|
exec:
|
||||||
|
- accounting_list_name: aaa
|
||||||
|
no_accounting: true
|
||||||
|
state: present
|
||||||
|
dot1x: none
|
||||||
|
rest: none
|
||||||
|
aaa_authorization:
|
||||||
|
commands:
|
||||||
|
- enable_level: 2
|
||||||
|
authorization_list_name: aa
|
||||||
|
use_data: local
|
||||||
|
state: present
|
||||||
|
- role_name: netadmin
|
||||||
|
authorization_list_name: aa
|
||||||
|
authorization_method: none
|
||||||
|
use_data: local
|
||||||
|
config_commands: True
|
||||||
|
role_only:
|
||||||
|
exec:
|
||||||
|
- authorization_list_name: aaa
|
||||||
|
authorization_method: if-authenticated
|
||||||
|
use_data: local
|
||||||
|
state: present
|
||||||
|
line_terminal:
|
||||||
|
vty 0:
|
||||||
|
authorization:
|
||||||
|
commands:
|
||||||
|
- enable_level: 2
|
||||||
|
authorization_list_name: aa
|
||||||
|
state: present
|
||||||
|
- role_name: netadmin
|
||||||
|
authorization_list_name: aa
|
||||||
|
state: present
|
||||||
|
exec:
|
||||||
|
- authorization_list_name: aa
|
||||||
|
state: present
|
||||||
|
accounting:
|
||||||
|
commands:
|
||||||
|
- enable_level: 2
|
||||||
|
accounting_list_name: aa
|
||||||
|
state: present
|
||||||
|
- role_name: netadmin
|
||||||
|
accounting_list_name: aa
|
||||||
|
state: absent
|
||||||
|
exec:
|
||||||
|
accounting_list_name: aa
|
||||||
|
state: present
|
||||||
|
authentication:
|
||||||
|
enable:
|
||||||
|
login: console
|
||||||
|
aaa_radius:
|
||||||
|
group: RADIUS
|
||||||
|
auth_method: pap
|
||||||
|
aaa_tacacs:
|
||||||
|
group: TACACS
|
||||||
|
aaa_authentication:
|
||||||
|
auth_list:
|
||||||
|
- name: default
|
||||||
|
login_or_enable: login
|
||||||
|
server: tacacs+
|
||||||
|
use_password: local
|
||||||
|
state: present
|
||||||
|
- name: console
|
||||||
|
server: radius
|
||||||
|
login_or_enable: login
|
||||||
|
use_password: local
|
5
roles/os9_aaa/tests/test.yaml
Normal file
5
roles/os9_aaa/tests/test.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
- hosts: datacenter
|
||||||
|
connection: network_cli
|
||||||
|
roles:
|
||||||
|
- dellemc.os9.os9_aaa
|
2
roles/os9_aaa/vars/main.yml
Normal file
2
roles/os9_aaa/vars/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
# vars file for dellemc.os9.os9_aaa
|
201
roles/os9_acl/LICENSE
Normal file
201
roles/os9_acl/LICENSE
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright (c) 2020, Dell EMC. All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
139
roles/os9_acl/README.md
Normal file
139
roles/os9_acl/README.md
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
ACL role
|
||||||
|
========
|
||||||
|
|
||||||
|
This role facilitates the configuration of an access-control list (ACL). It supports the configuration of different types of ACLs (standard and extended) for both IPv4 and IPv6, and assigns the access-class to the line terminals.
|
||||||
|
|
||||||
|
The ACL role requires an SSH connection for connectivity to a Dell EMC Networking device. You can use any of the built-in OS connection variables.
|
||||||
|
|
||||||
|
|
||||||
|
Role variables
|
||||||
|
--------------
|
||||||
|
|
||||||
|
- Role is abstracted using the *ansible_network_os* variable that can take dellemc.os9.os9 as a value
|
||||||
|
- If *os9_cfg_generate* is set to true, the variable generates the role configuration commands in a file
|
||||||
|
- Any role variable with a corresponding state variable set to absent negates the configuration of that variable
|
||||||
|
- Setting an empty value for any variable negates the corresponding configuration
|
||||||
|
- Variables and values are case-sensitive
|
||||||
|
|
||||||
|
**os9_acl keys**
|
||||||
|
|
||||||
|
| Key | Type | Description | Support |
|
||||||
|
|------------|---------------------------|---------------------------------------------------------|-----------------------|
|
||||||
|
| ``type`` | string (required): ipv4, ipv6, mac | Configures the L3 (IPv4/IPv6) or L2 (MAC) access-control list | os9 |
|
||||||
|
| ``name`` | string (required) | Configures the name of the access-control list | os9 |
|
||||||
|
| ``description`` | string | Configures the description about the access-control list | os9 |
|
||||||
|
| ``remark`` | list | Configures the ACL remark (see ``remark.*``) | os9 |
|
||||||
|
| ``remark.number`` | integer (required) | Configures the remark sequence number | os9 |
|
||||||
|
| ``remark.description`` | string | Configures the remark description | os9 |
|
||||||
|
| ``remark.state`` | string: absent,present\* | Deletes the configured remark for an ACL entry if set to absent | os9 |
|
||||||
|
| ``extended`` | boolean: true,false | Configures an extended ACL type if set to true; configures a standard ACL if set to false | os9 |
|
||||||
|
| ``entries`` | list | Configures ACL rules (see ``seqlist.*``) | os9 |
|
||||||
|
| ``entries.number`` | integer (required) | Specifies the sequence number of the ACL rule | os9 |
|
||||||
|
| ``entries.permit`` | boolean (required): true,false | Specifies the rule to permit packets if set to true; specifies to reject packets if set to false | os9 |
|
||||||
|
| ``entries.protocol`` | string (required) | Specifies the type of protocol or the protocol number to filter | os9 |
|
||||||
|
| ``entries.source`` | string (required) | Specifies the source address to match in the packets | os9 |
|
||||||
|
| ``entries.src_condition`` | string | Specifies the condition to filter packets from the source address; ignored if MAC | os9 |
|
||||||
|
| ``entries.destination`` | string (required) | Specifies the destination address to match in the packets | os9 |
|
||||||
|
| ``entries.dest_condition`` | string | Specifies the condition to filter packets to the destination address | os9 |
|
||||||
|
| ``entries.other_options`` | string | Specifies the other options applied on packets (count, log, order, monitor, and so on) | os9 |
|
||||||
|
| ``entries.state`` | string: absent,present\* | Deletes the rule from the ACL if set to absent | os9 |
|
||||||
|
| ``stage_ingress`` | list | Configures ingress ACL to the interface (see ``stage_ingress.*``) | os9 |
|
||||||
|
| ``stage_ingress.name`` | string (required) | Configures the ingress ACL filter to the interface with this interface name | os9 |
|
||||||
|
| ``stage_ingress.state`` | string: absent,present\* | Deletes the configured ACL from the interface if set to absent | os9 |
|
||||||
|
| ``stage_ingress.seq_number`` | integer | Configure the sequence number (greater than 0) to rank precedence for this interface and direction |
|
||||||
|
| ``stage_egress`` | list | Configures egress ACL to the interface (see ``stage_egress.*``) | os9 |
|
||||||
|
| ``stage_egress.name`` | string (required) | Configures the egress ACL filter to the interface with this interface name | os9 |
|
||||||
|
| ``stage_egress.state`` | string: absent,present\* | Deletes the configured egress ACL from the interface if set to absent | os9 |
|
||||||
|
| ``lineterminal`` | list | Configures the terminal to apply the ACL (see ``lineterminal.*``) | os9 |
|
||||||
|
| ``lineterminal.line`` | string (required) | Configures access-class on the line terminal | os9 |
|
||||||
|
| ``lineterminal.state`` | string: absent,present\* | Deletes the access-class from line terminal if set to absent | os9 |
|
||||||
|
| ``state`` | string: absent,present\* | Deletes the ACL if set to absent | os9 |
|
||||||
|
|
||||||
|
> **NOTE**: Asterisk (\*) denotes the default value if none is specified.
|
||||||
|
|
||||||
|
Connection variables
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Ansible Dell EMC Networking roles require connection information to establish communication with the nodes in inventory. This information can exist in the Ansible *group_vars* or *host_vars* directories or inventory, or in the playbook itself.
|
||||||
|
|
||||||
|
| Key | Required | Choices | Description |
|
||||||
|
|-------------|----------|------------|-------------------------------------------------------|
|
||||||
|
| ``ansible_host`` | yes | | Specifies the hostname or address for connecting to the remote device over the specified transport |
|
||||||
|
| ``ansible_port`` | no | | Specifies the port used to build the connection to the remote device; if value is unspecified, the ANSIBLE_REMOTE_PORT option is used; it defaults to 22 |
|
||||||
|
| ``ansible_ssh_user`` | no | | Specifies the username that authenticates the CLI login for the connection to the remote device; if value is unspecified, the ANSIBLE_REMOTE_USER environment variable value is used |
|
||||||
|
| ``ansible_ssh_pass`` | no | | Specifies the password that authenticates the connection to the remote device. |
|
||||||
|
| ``ansible_become`` | no | yes, no\* | Instructs the module to enter privileged mode on the remote device before sending any commands; if value is unspecified, the ANSIBLE_BECOME environment variable value is used, and the device attempts to execute all commands in non-privileged mode |
|
||||||
|
| ``ansible_become_method`` | no | enable, sudo\* | Instructs the module to allow the become method to be specified for handling privilege escalation; if value is unspecified, the ANSIBLE_BECOME_METHOD environment variable value is used. |
|
||||||
|
| ``ansible_become_pass`` | no | | Specifies the password to use if required to enter privileged mode on the remote device; if ``ansible_become`` is set to no this key is not applicable. |
|
||||||
|
| ``ansible_network_os`` | yes /os9, null\* | This value is used to load the correct terminal and cliconf plugins to communicate with the remote device. |
|
||||||
|
|
||||||
|
> **NOTE**: Asterisk (_*_) denotes the default value if none is specified.
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
|
The *os9_acl* role is built on modules included in the core Ansible code. These modules were added in Ansible version 2.2.0.
|
||||||
|
|
||||||
|
Example playbook
|
||||||
|
----------------
|
||||||
|
|
||||||
|
This example uses the *os9_acl* role to configure different types of ACLs (standard and extended) for both IPv4 and IPv6 and assigns the access-class to the line terminals. The example creates a *hosts* file with the switch details and corresponding variables. The hosts file should define the *ansible_network_os* variable with the corresponding Dell EMC networking OS name.
|
||||||
|
|
||||||
|
When *os9_cfg_generate* is set to true, it generates the configuration commands as a .part file in the *build_dir* path. By default it is set to false. It writes a simple playbook that only references the *os9_acl* role.
|
||||||
|
|
||||||
|
**Sample hosts file**
|
||||||
|
|
||||||
|
leaf1 ansible_host= <ip_address>
|
||||||
|
|
||||||
|
**Sample host_vars/leaf1**
|
||||||
|
|
||||||
|
hostname: leaf1
|
||||||
|
ansible_become: yes
|
||||||
|
ansible_become_method: xxxxx
|
||||||
|
ansible_become_pass: xxxxx
|
||||||
|
ansible_ssh_user: xxxxx
|
||||||
|
ansible_ssh_pass: xxxxx
|
||||||
|
ansible_network_os: dellemc.os9.os9
|
||||||
|
build_dir: ../temp/os9
|
||||||
|
os9_acl:
|
||||||
|
- type: ipv4
|
||||||
|
name: ssh-only
|
||||||
|
description: ipv4acl
|
||||||
|
extended: true
|
||||||
|
remark:
|
||||||
|
- number: 5
|
||||||
|
description: "ipv4remark"
|
||||||
|
entries:
|
||||||
|
- number: 5
|
||||||
|
permit: true
|
||||||
|
protocol: tcp
|
||||||
|
source: any
|
||||||
|
src_condition: ack
|
||||||
|
destination: any
|
||||||
|
dest_condition: eq 22
|
||||||
|
other_options: count
|
||||||
|
state: present
|
||||||
|
stage_ingress:
|
||||||
|
- name: fortyGigE 1/28
|
||||||
|
state: present
|
||||||
|
stage_egress:
|
||||||
|
- name: fortyGigE 1/28
|
||||||
|
state: present
|
||||||
|
lineterminal:
|
||||||
|
- line: vty 1
|
||||||
|
state: present
|
||||||
|
- line: vty 2
|
||||||
|
state: absent
|
||||||
|
state: present
|
||||||
|
|
||||||
|
**Simple playbook to setup system - leaf.yaml**
|
||||||
|
|
||||||
|
- hosts: leaf1
|
||||||
|
roles:
|
||||||
|
- dellemc.os9.os9_acl
|
||||||
|
|
||||||
|
**Run**
|
||||||
|
|
||||||
|
ansible-playbook -i hosts leaf.yaml
|
||||||
|
|
||||||
|
(c) 2017-2020 Dell Inc. or its subsidiaries. All Rights Reserved.
|
2
roles/os9_acl/defaults/main.yml
Normal file
2
roles/os9_acl/defaults/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
# defaults file for dellemc.os9.os9_acl
|
2
roles/os9_acl/handlers/main.yml
Normal file
2
roles/os9_acl/handlers/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
# handlers file for dellemc.os9.os9_aaa
|
18
roles/os9_acl/meta/main.yml
Normal file
18
roles/os9_acl/meta/main.yml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Copyright (c) 2017-2020 Dell Inc. or its subsidiaries. All Rights Reserved.
|
||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Dell EMC Networking Engineering
|
||||||
|
description: The os9_acl role facilitates the configuration of access control list (ACL) attributes in devices running Dell EMC Networking Operating Systems.
|
||||||
|
license: Apache 2.0
|
||||||
|
min_ansible_version: 2.2
|
||||||
|
|
||||||
|
platforms:
|
||||||
|
- name: os9
|
||||||
|
|
||||||
|
galaxy_tags:
|
||||||
|
- networking
|
||||||
|
- dell
|
||||||
|
- emc
|
||||||
|
- dellemc
|
||||||
|
- os9
|
||||||
|
|
16
roles/os9_acl/tasks/main.yml
Normal file
16
roles/os9_acl/tasks/main.yml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
#tasks file for os9
|
||||||
|
- name: "Generating ACL configuration for os9"
|
||||||
|
template:
|
||||||
|
src: os9_acl.j2
|
||||||
|
dest: "{{ build_dir }}/acl9_{{ hostname }}.conf.part"
|
||||||
|
when: (ansible_network_os is defined and ansible_network_os == "dellemc.os9.os9") and ((os9_cfg_generate | default('False')) | bool)
|
||||||
|
# notify: save config os9
|
||||||
|
register: generate_output
|
||||||
|
|
||||||
|
- name: "Provisioning ACL configuration for os9"
|
||||||
|
os9_config:
|
||||||
|
src: os9_acl.j2
|
||||||
|
when: (ansible_network_os is defined and ansible_network_os == "dellemc.os9.os9")
|
||||||
|
# notify: save config os9
|
||||||
|
register: output
|
277
roles/os9_acl/templates/os9_acl.j2
Normal file
277
roles/os9_acl/templates/os9_acl.j2
Normal file
|
@ -0,0 +1,277 @@
|
||||||
|
#jinja2: trim_blocks: True,lstrip_blocks: True
|
||||||
|
{####################################
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
Configure ACL commands for os9 devices
|
||||||
|
|
||||||
|
os9_acl:
|
||||||
|
- name: ssh-only
|
||||||
|
type: ipv4
|
||||||
|
description: acl
|
||||||
|
extended: true
|
||||||
|
remark:
|
||||||
|
- number: 1
|
||||||
|
description: helloworld
|
||||||
|
state: present
|
||||||
|
entries:
|
||||||
|
- number: 10
|
||||||
|
permit: true
|
||||||
|
protocol: tcp
|
||||||
|
source: any
|
||||||
|
destination: any
|
||||||
|
src_condition: eq 22
|
||||||
|
dest_condition: ack
|
||||||
|
other_options: count
|
||||||
|
state: present
|
||||||
|
stage_ingress:
|
||||||
|
- name: fortyGigE 1/8
|
||||||
|
state: present
|
||||||
|
- name: fortyGigE 1/9
|
||||||
|
state: present
|
||||||
|
stage_egress:
|
||||||
|
- name: fortyGigE 1/19
|
||||||
|
state: present
|
||||||
|
lineterminal:
|
||||||
|
- line: vty 0
|
||||||
|
state: present
|
||||||
|
- line: vty 1
|
||||||
|
state: present
|
||||||
|
state: present
|
||||||
|
- name: ipv6-ssh-only
|
||||||
|
type: ipv6
|
||||||
|
entries:
|
||||||
|
- number: 10
|
||||||
|
permit: true
|
||||||
|
protocol: ipv6
|
||||||
|
source: 2001:4898::/32
|
||||||
|
destination: any
|
||||||
|
- number: 20
|
||||||
|
permit: true
|
||||||
|
protocol: tcp
|
||||||
|
source: any
|
||||||
|
src_condition: ack
|
||||||
|
destination: any
|
||||||
|
- number: 40
|
||||||
|
permit: true
|
||||||
|
protocol: tcp
|
||||||
|
source: any
|
||||||
|
destination: any
|
||||||
|
state: present
|
||||||
|
lineterminal:
|
||||||
|
- line: vty 0
|
||||||
|
state: present
|
||||||
|
- line: vty 1
|
||||||
|
state: present
|
||||||
|
#####################################}
|
||||||
|
{% if os9_acl is defined and os9_acl %}
|
||||||
|
{% for val in os9_acl
|
||||||
|
%}
|
||||||
|
{% if val.name is defined and val.name %}
|
||||||
|
{% if val.state is defined and val.state == "absent" %}
|
||||||
|
{% if val.type is defined and val.type == "ipv4" %}
|
||||||
|
{% if val.extended is defined and val.extended %}
|
||||||
|
no ip access-list extended {{ val.name }}
|
||||||
|
{% else %}
|
||||||
|
no ip access-list standard {{ val.name }}
|
||||||
|
{% endif %}
|
||||||
|
{% elif val.type is defined and val.type == "ipv6" %}
|
||||||
|
no ipv6 access-list {{ val.name }}
|
||||||
|
{% elif val.type is defined and val.type == "mac" %}
|
||||||
|
{% if val.extended is defined and val.extended %}
|
||||||
|
no mac access-list extended {{ val.name }}
|
||||||
|
{% else %}
|
||||||
|
no mac access-list standard {{ val.name }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if val.type is defined and val.type == "ipv4" %}
|
||||||
|
{% if val.extended is defined and val.extended %}
|
||||||
|
ip access-list extended {{ val.name }}
|
||||||
|
{% else %}
|
||||||
|
ip access-list standard {{ val.name }}
|
||||||
|
{% endif %}
|
||||||
|
{% elif val.type is defined and val.type == "ipv6" %}
|
||||||
|
ipv6 access-list {{ val.name }}
|
||||||
|
{% elif val.type is defined and val.type == "mac" %}
|
||||||
|
{% if val.extended is defined and val.extended %}
|
||||||
|
mac access-list extended {{ val.name }}
|
||||||
|
{% else %}
|
||||||
|
mac access-list standard {{ val.name }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if val.description is defined %}
|
||||||
|
{% if val.description %}
|
||||||
|
description {{ val.description }}
|
||||||
|
{% else %}
|
||||||
|
no description a
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if val.remark is defined and val.remark %}
|
||||||
|
{% for remark in val.remark %}
|
||||||
|
{% if remark.number is defined and remark.number %}
|
||||||
|
{% if remark.state is defined and remark.state == "absent" %}
|
||||||
|
no remark {{ remark.number }}
|
||||||
|
{% else %}
|
||||||
|
{% if remark.description is defined and remark.description %}
|
||||||
|
remark {{ remark.number }} {{ remark.description }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if val.entries is defined and val.entries %}
|
||||||
|
{% for rule in val.entries %}
|
||||||
|
{% if rule.number is defined and rule.number %}
|
||||||
|
{% if rule.state is defined and rule.state == "absent" %}
|
||||||
|
no seq {{ rule.number }}
|
||||||
|
{% else %}
|
||||||
|
{% if rule.permit is defined %}
|
||||||
|
{% if rule.permit %}
|
||||||
|
{% set is_permit = "permit" %}
|
||||||
|
{% else %}
|
||||||
|
{% set is_permit = "deny" %}
|
||||||
|
{% endif %}
|
||||||
|
{% if val.type is defined and val.type == "mac" %}
|
||||||
|
{% if rule.source is defined and rule.source %}
|
||||||
|
{% if rule.destination is defined and rule.destination %}
|
||||||
|
{% if rule.other_options is defined and rule.other_options %}
|
||||||
|
{% if rule.other_options == "log" %}
|
||||||
|
{% set other_options = rule.other_options + ' threshold-in-msgs 10 interval 5' %}
|
||||||
|
{% else %}
|
||||||
|
{% set other_options = rule.other_options %}
|
||||||
|
{% endif %}
|
||||||
|
seq {{ rule.number }} {{ is_permit }} {{ rule.source }} {{ rule.destination }} {{ other_options }}
|
||||||
|
{% else %}
|
||||||
|
seq {{ rule.number }} {{ is_permit }} {{ rule.source }} {{ rule.destination }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if rule.protocol is defined and rule.protocol %}
|
||||||
|
{% if rule.source is defined and rule.source %}
|
||||||
|
{% if rule.destination is defined and rule.destination %}
|
||||||
|
{% if rule.src_condition is defined and rule.src_condition %}
|
||||||
|
{% if rule.dest_condition is defined and rule.dest_condition %}
|
||||||
|
{% if rule.other_options is defined and rule.other_options %}
|
||||||
|
{% if rule.other_options == "log" %}
|
||||||
|
{% set other_options = rule.other_options + ' threshold-in-msgs 10 interval 5' %}
|
||||||
|
{% else %}
|
||||||
|
{% set other_options = rule.other_options %}
|
||||||
|
{% endif %}
|
||||||
|
seq {{ rule.number }} {{ is_permit }} {{ rule.protocol }} {{ rule.source }} {{ rule.src_condition }} {{ rule.destination }} {{ rule.dest_condition }} {{ other_options }}
|
||||||
|
{% else %}
|
||||||
|
seq {{ rule.number }} {{ is_permit }} {{ rule.protocol }} {{ rule.source }} {{ rule.src_condition }} {{ rule.destination }} {{ rule.dest_condition }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if rule.other_options is defined and rule.other_options %}
|
||||||
|
{% if rule.other_options == "log" %}
|
||||||
|
{% set other_options = rule.other_options + ' threshold-in-msgs 10 interval 5' %}
|
||||||
|
{% else %}
|
||||||
|
{% set other_options = rule.other_options %}
|
||||||
|
{% endif %}
|
||||||
|
seq {{ rule.number }} {{ is_permit }} {{ rule.protocol }} {{ rule.source }} {{ rule.src_condition }} {{ rule.destination }} {{ other_options }}
|
||||||
|
{% else %}
|
||||||
|
seq {{ rule.number }} {{ is_permit }} {{ rule.protocol }} {{ rule.source }} {{ rule.src_condition }} {{ rule.destination }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if rule.dest_condition is defined and rule.dest_condition %}
|
||||||
|
{% if rule.other_options is defined and rule.other_options %}
|
||||||
|
{% if rule.other_options == "log" %}
|
||||||
|
{% set other_options = rule.other_options + ' threshold-in-msgs 10 interval 5' %}
|
||||||
|
{% else %}
|
||||||
|
{% set other_options = rule.other_options %}
|
||||||
|
{% endif %}
|
||||||
|
seq {{ rule.number }} {{ is_permit }} {{ rule.protocol }} {{ rule.source }} {{ rule.destination }} {{ rule.dest_condition }} {{ other_options }}
|
||||||
|
{% else %}
|
||||||
|
seq {{ rule.number }} {{ is_permit }} {{ rule.protocol }} {{ rule.source }} {{ rule.destination }} {{ rule.dest_condition }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if rule.other_options is defined and rule.other_options %}
|
||||||
|
{% if rule.other_options == "log" %}
|
||||||
|
{% set other_options = rule.other_options + ' threshold-in-msgs 10 interval 5' %}
|
||||||
|
{% else %}
|
||||||
|
{% set other_options = rule.other_options %}
|
||||||
|
{% endif %}
|
||||||
|
seq {{ rule.number }} {{ is_permit }} {{ rule.protocol }} {{ rule.source }} {{ rule.destination }} {{ other_options }}
|
||||||
|
{% else %}
|
||||||
|
seq {{ rule.number }} {{ is_permit }} {{ rule.protocol }} {{ rule.source }} {{ rule.destination }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if val.lineterminal is defined and val.lineterminal %}
|
||||||
|
{% if val.type is defined and not val.type == "mac" %}
|
||||||
|
{% for vty in val.lineterminal %}
|
||||||
|
{% if vty.line is defined and vty.line %}
|
||||||
|
line {{ vty.line }}
|
||||||
|
{% if vty.state is defined and vty.state == "absent" %}
|
||||||
|
no access-class {{ val.name }} {{ val.type }}
|
||||||
|
{% else %}
|
||||||
|
access-class {{ val.name }} {{ val.type }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if val.stage_ingress is defined and val.stage_ingress %}
|
||||||
|
{% for intf in val.stage_ingress %}
|
||||||
|
{% if intf.state is defined and intf.state == "absent" %}
|
||||||
|
{% if intf.name is defined and intf.name %}
|
||||||
|
interface {{ intf.name }}
|
||||||
|
{% if val.type is defined and val.type == "mac" %}
|
||||||
|
no mac access-group {{ val.name }} in
|
||||||
|
{% else %}
|
||||||
|
no ip access-group {{ val.name }} in
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if intf.name is defined and intf.name %}
|
||||||
|
interface {{ intf.name }}
|
||||||
|
{% if val.type is defined and val.type == "mac" %}
|
||||||
|
mac access-group {{ val.name }} in
|
||||||
|
{% else %}
|
||||||
|
ip access-group {{ val.name }} in
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if val.stage_egress is defined and val.stage_egress %}
|
||||||
|
{% for intf in val.stage_egress %}
|
||||||
|
{% if intf.state is defined and intf.state == "absent" %}
|
||||||
|
{% if intf.name is defined and intf.name %}
|
||||||
|
interface {{ intf.name }}
|
||||||
|
{% if val.type is defined and val.type == "mac" %}
|
||||||
|
no mac access-group {{ val.name }} out
|
||||||
|
{% else %}
|
||||||
|
no ip access-group {{ val.name }} out
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if intf.name is defined and intf.name %}
|
||||||
|
interface {{ intf.name }}
|
||||||
|
{% if val.type is defined and val.type == "mac" %}
|
||||||
|
mac access-group {{ val.name }} out
|
||||||
|
{% else %}
|
||||||
|
ip access-group {{ val.name }} out
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
20
roles/os9_acl/tests/inventory.yaml
Normal file
20
roles/os9_acl/tests/inventory.yaml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
spine1 ansible_host=100.94.210.44
|
||||||
|
spine2 ansible_host=10.11.182.26
|
||||||
|
leaf1 ansible_host=10.11.182.27
|
||||||
|
leaf2 ansible_host=10.11.182.28
|
||||||
|
leaf3 ansible_host=10.11.182.29
|
||||||
|
leaf4 ansible_host=10.11.182.30
|
||||||
|
|
||||||
|
[spine]
|
||||||
|
spine1
|
||||||
|
spine2
|
||||||
|
|
||||||
|
[leaf]
|
||||||
|
leaf1
|
||||||
|
leaf2
|
||||||
|
leaf3
|
||||||
|
leaf4
|
||||||
|
|
||||||
|
[datacenter:children]
|
||||||
|
spine
|
||||||
|
leaf
|
88
roles/os9_acl/tests/main.os9.yaml
Normal file
88
roles/os9_acl/tests/main.os9.yaml
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
---
|
||||||
|
# vars file for dellemc.os9.os9_acl,
|
||||||
|
# below gives a sample configuration
|
||||||
|
# Sample variables for OS9 device
|
||||||
|
os9_acl:
|
||||||
|
- name: ssh-only-mac
|
||||||
|
type: mac
|
||||||
|
description: macacl
|
||||||
|
extended: true
|
||||||
|
remark:
|
||||||
|
- number: 1
|
||||||
|
description: mac
|
||||||
|
state: present
|
||||||
|
entries:
|
||||||
|
- number: 5
|
||||||
|
permit: true
|
||||||
|
protocol: tcp
|
||||||
|
source: any
|
||||||
|
destination: any
|
||||||
|
dest_condition: eq 2
|
||||||
|
other_options: count
|
||||||
|
state: present
|
||||||
|
- number: 6
|
||||||
|
permit: false
|
||||||
|
protocol: tcp
|
||||||
|
source: bb:bb:bb:bb:bb:bb ff:ff:ff:ff:ff:ff
|
||||||
|
destination: any
|
||||||
|
dest_condition: log
|
||||||
|
state: present
|
||||||
|
stage_ingress:
|
||||||
|
- name: fortyGigE 1/28
|
||||||
|
state: present
|
||||||
|
- name: fortyGigE 1/27
|
||||||
|
state: present
|
||||||
|
stage_egress:
|
||||||
|
- name: fortyGigE 1/28
|
||||||
|
state: present
|
||||||
|
lineterminal:
|
||||||
|
- line: vty 1
|
||||||
|
state: present
|
||||||
|
- line: vty 2
|
||||||
|
state: absent
|
||||||
|
- line: vty 3
|
||||||
|
state: present
|
||||||
|
- name: ipv6-ssh-only
|
||||||
|
type: ipv6
|
||||||
|
description: ipv6acl
|
||||||
|
remark:
|
||||||
|
- number: 1
|
||||||
|
description: ipv6
|
||||||
|
entries:
|
||||||
|
- number: 10
|
||||||
|
permit: true
|
||||||
|
protocol: ipv6
|
||||||
|
source: 2001:4898::/32
|
||||||
|
destination: any
|
||||||
|
- number: 20
|
||||||
|
permit: true
|
||||||
|
protocol: tcp
|
||||||
|
source: any
|
||||||
|
src_condition: eq 2
|
||||||
|
destination: 2404:f801::/32
|
||||||
|
- number: 30
|
||||||
|
permit: true
|
||||||
|
protocol: tcp
|
||||||
|
source: any
|
||||||
|
destination: 2a01:110::/31
|
||||||
|
dest_condition: ack
|
||||||
|
- number: 40
|
||||||
|
permit: true
|
||||||
|
protocol: tcp
|
||||||
|
source: any
|
||||||
|
destination: any
|
||||||
|
stage_ingress:
|
||||||
|
- name: fortyGigE 1/26
|
||||||
|
state: present
|
||||||
|
- name: fortyGigE 1/27
|
||||||
|
state: present
|
||||||
|
stage_egress:
|
||||||
|
- name: fortyGigE 1/26
|
||||||
|
state: present
|
||||||
|
lineterminal:
|
||||||
|
- line: vty 0
|
||||||
|
state: absent
|
||||||
|
- line: vty 1
|
||||||
|
- line: vty 2
|
||||||
|
- line: vty 3
|
||||||
|
state: present
|
5
roles/os9_acl/tests/test.yaml
Normal file
5
roles/os9_acl/tests/test.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
- hosts: datacenter
|
||||||
|
connection: network_cli
|
||||||
|
roles:
|
||||||
|
- dellemc.os9.os9_acl
|
2
roles/os9_acl/vars/main.yml
Normal file
2
roles/os9_acl/vars/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
# vars file for dellemc.os9.os9_acl
|
201
roles/os9_bgp/LICENSE
Normal file
201
roles/os9_bgp/LICENSE
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright (c) 2020, Dell EMC. All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
229
roles/os9_bgp/README.md
Normal file
229
roles/os9_bgp/README.md
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
BGP role
|
||||||
|
========
|
||||||
|
|
||||||
|
This role facilitates the configuration of border gateway protocol (BGP) attributes. It supports the configuration of router ID, networks, neighbors, and maximum path. This role is abstracted for Dell EMC platforms running OS9.
|
||||||
|
|
||||||
|
The BGP role requires an SSH connection for connectivity to a Dell EMC Networking device. You can use any of the built-in OS connection variables.
|
||||||
|
|
||||||
|
|
||||||
|
Role variables
|
||||||
|
--------------
|
||||||
|
|
||||||
|
- Role is abstracted using the *ansible_network_os* variable that can take dellemc.os9.os9 vas a value
|
||||||
|
- If variable *os9_cfg_generate* is set to true, it generates the role configuration commands in a file
|
||||||
|
- Any role variable with a corresponding state variable setting to absent negates the configuration of that variable
|
||||||
|
- Setting an empty value for any variable negates the corresponding configuration
|
||||||
|
- Variables and values are case-sensitive
|
||||||
|
|
||||||
|
**os9_bgp keys**
|
||||||
|
|
||||||
|
| Key | Type | Description | Support |
|
||||||
|
|------------|---------------------------|---------------------------------------------------------|-----------------------|
|
||||||
|
| ``asn`` | string (required) | Configures the autonomous system (AS) number of the local BGP instance | os9 |
|
||||||
|
| ``router_id`` | string | Configures the IP address of the local BGP router instance | os9 |
|
||||||
|
| ``graceful_restart`` | boolean | Configures graceful restart capability | os9 |
|
||||||
|
| ``graceful_restart.state`` | string: absent,present\* | Removes graceful restart capability if set to absent | os9 |
|
||||||
|
| ``maxpath_ibgp`` | integer | qqConfigures the maximum number of paths to forward packets through iBGP (1 to 64; default 1) | os9 |
|
||||||
|
| ``maxpath_ebgp`` | integer | Configures the maximum number of paths to forward packets through eBGP (1 to 64; default 1) | os9 |
|
||||||
|
| ``best_path`` | list | Configures the default best-path selection (see ``best_path.*``) | os9 |
|
||||||
|
| ``best_path.as_path`` | string (required): ignore,multipath-relax | Configures the AS path used for the best-path computation | os9 |
|
||||||
|
| ``best_path.as_path_state`` | string: absent,present\* | Deletes the AS path configuration if set to absent | os9 |
|
||||||
|
| ``best_path.ignore_router_id`` | boolean: true,false | Ignores the router identifier in best-path computation if set to true | os9 |
|
||||||
|
| ``best_path.med`` | list | Configures the MED attribute (see ``med.*``) | os9 |
|
||||||
|
| ``med.attribute`` | string (required): confed,missing-as-best | Configures the MED attribute used for the best-path computation | os9 |
|
||||||
|
| ``med.state`` | string: absent,present\* | Deletes the MED attribute if set to absent | os9, |
|
||||||
|
| ``ipv4_network`` | list | Configures an IPv4 BGP networks (see ``ipv4_network.*``) | , os9, |
|
||||||
|
| ``ipv4_network.address`` | string (required) | Configures the IPv4 address of the BGP network (A.B.C.D/E format) | os9 |
|
||||||
|
| ``ipv4_network.state`` | string: absent,present\* | Deletes an IPv4 BGP network if set to absent | os9 |
|
||||||
|
| ``ipv6_network`` | list | Configures an IPv6 BGP network (see ``ipv6_network.*``) | os9 |
|
||||||
|
| ``ipv6_network.address`` | string (required) | Configures the IPv6 address of the BGP network (2001:4898:5808:ffa2::1/126 format) | os9 |
|
||||||
|
| ``ipv6_network.state`` | string: absent,present\* | Deletes an IPv6 BGP network if set to absent | os9 |
|
||||||
|
| ``neighbor`` | list | Configures IPv4 BGP neighbors (see ``neighbor.*``) | os9 |
|
||||||
|
| ``neighbor.ip`` | string (required) | Configures the IPv4 address of the BGP neighbor (10.1.1.1) | os9 |
|
||||||
|
| ``neighbor.interface`` | string | Configures the BGP neighbor interface details | |
|
||||||
|
| ``neighbor.name`` | string (required) | Configures the BGP peer-group with this name; supported only when the neighbor is a peer group; mutually exclusive with *neighbor.ip* | os9 |
|
||||||
|
| ``neighbor.type`` | string (required): ipv4,ipv6,peergroup | Specifies the BGP neighbor type | os9 |
|
||||||
|
| ``neighbor.remote_asn`` | string (required) | Configures the remote AS number of the BGP neighbor | os9 |
|
||||||
|
| ``neighbor.remote_asn_state`` | string: absent,present\* | Deletes the remote AS number from the peer group if set to absent; supported only when *neighbor.type* is "peergroup" | os9 |
|
||||||
|
| ``neighbor.timer`` | string | Configures neighbor timers (<int> <int>); 5 10, where 5 is the keepalive interval and 10 is the holdtime | os9 |
|
||||||
|
| ``neighbor.default_originate`` | boolean: true, false\* | Configures default originate routes to the BGP neighbor | os9 |
|
||||||
|
| ``neighbor.peergroup`` | string | Configures neighbor to BGP peer-group (configured peer-group name) | os9 |
|
||||||
|
| ``neighbor.peergroup_state`` | string: absent,present\* | Deletes the IPv4 BGP neighbor from the peer-group if set to absent | os9 |
|
||||||
|
| ``neighbor.distribute_list`` | list | Configures the distribute list to filter networks from routing updates (see ``distribute_list.*``) | os9 |
|
||||||
|
| ``distribute_list.in`` | string | Configures the name of the prefix-list to filter incoming packets | os9 |
|
||||||
|
| ``distribute_list.in_state`` | string: absent,present\* | Deletes the filter at incoming packets if set to absent | os9 |
|
||||||
|
| ``distribute_list.out`` | string | Configures the name of the prefix-list to filter outgoing packets | os9 |
|
||||||
|
| ``distribute_list.out_state`` | string: absent,present\* | Deletes the filter at outgoing packets if set to absent | os9 |
|
||||||
|
| ``neighbor.admin`` | string: up,down | Configures the administrative state of the neighbor | os9 |
|
||||||
|
| ``neighbor.adv_interval`` | integer | Configures the advertisement interval of the neighbor | os9 |
|
||||||
|
| ``neighbor.fall_over`` | string: absent,present | Configures the session fall on peer-route loss | os9 |
|
||||||
|
| ``neighbor.sender_loop_detect`` | boolean: true,false | Enables/disables the sender-side loop detect for neighbors | os9 |
|
||||||
|
| ``neighbor.src_loopback`` | integer | Configures the source loopback interface for routing packets | os9 |
|
||||||
|
| ``neighbor.src_loopback_state`` | string: absent,present\* | Deletes the source for routing packets if set to absent | os9 |
|
||||||
|
| ``neighbor.ebgp_multihop`` | integer | Configures the maximum-hop count value allowed in eBGP neighbors that are not directly connected (default 255) | os9 |
|
||||||
|
| ``neighbor.passive`` | boolean: true,false\* | Configures the passive BGP peer group; supported only when neighbor is a peer-group | os9 |
|
||||||
|
| ``neighbor.subnet`` | string (required) | Configures the passive BGP neighbor to this subnet; required together with the *neighbor.passive* key for os9 devices | , os9, |
|
||||||
|
| ``neighbor.subnet_state`` | string: absent,present\* | Deletes the subnet range set for dynamic IPv4 BGP neighbor if set to absent | os9 |
|
||||||
|
| ``neighbor.limit`` | integer | Configures maximum dynamic peers count (key is required together with ``neighbor.subnet``) | |
|
||||||
|
| ``neighbor.bfd`` | boolean | Enables BDF for neighbor | |
|
||||||
|
| ``neighbor.state`` | string: absent,present\* | Deletes the IPv4 BGP neighbor if set to absent | os9 |
|
||||||
|
| ``redistribute`` | list | Configures the redistribute list to get information from other routing protocols (see ``redistribute.*``) | os9 |
|
||||||
|
| ``redistribute.route_type`` | string (required): static,connected | Configures the name of the routing protocol to redistribute | os9 |
|
||||||
|
| ``redistribute.route_map_name`` | string | Configures the route-map to redistribute | os9 |
|
||||||
|
| ``redistribute.route_map`` | string: absent,present\* | Deletes the route-map to redistribute if set to absent | os9 |
|
||||||
|
| ``redistribute.address_type`` | string (required): ipv4,ipv6 | Configures the address type of IPv4 or IPv6 routes | os9 |
|
||||||
|
| ``redistribute.state`` | string: absent,present\* | Deletes the redistribution information if set to absent | os9 |
|
||||||
|
| ``state`` | string: absent,present\* | Deletes the local router BGP instance if set to absent | os9 |
|
||||||
|
|
||||||
|
> **NOTE**: Asterisk (\*) denotes the default value if none is specified.
|
||||||
|
|
||||||
|
Connection variables
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Ansible Dell EMC Networking roles require connection information to establish communication with the nodes in your inventory. This information can exist in the Ansible *group_vars* or *host_vars* directories or inventory, or in the playbook itself.
|
||||||
|
|
||||||
|
| Key | Required | Choices | Description |
|
||||||
|
|-------------|----------|------------|-----------------------------------------------------|
|
||||||
|
| ``ansible_host`` | yes | | Specifies the hostname or address for connecting to the remote device over the specified transport |
|
||||||
|
| ``ansible_port`` | no | | Specifies the port used to build the connection to the remote device; if value is unspecified, the ANSIBLE_REMOTE_PORT option is used; it defaults to 22 |
|
||||||
|
| ``ansible_ssh_user`` | no | | Specifies the username that authenticates the CLI login for the connection to the remote device; if value is unspecified, the ANSIBLE_REMOTE_USER environment variable value is used |
|
||||||
|
| ``ansible_ssh_pass`` | no | | Specifies the password that authenticates the connection to the remote device. |
|
||||||
|
| ``ansible_become`` | no | yes, no\* | Instructs the module to enter privileged mode on the remote device before sending any commands; if value is unspecified, the ANSIBLE_BECOME environment variable value is used, and the device attempts to execute all commands in non-privileged mode |
|
||||||
|
| ``ansible_become_method`` | no | enable, sudo\* | Instructs the module to allow the become method to be specified for handling privilege escalation; if value is unspecified, the ANSIBLE_BECOME_METHOD environment variable value is used. |
|
||||||
|
| ``ansible_become_pass`` | no | | Specifies the password to use if required to enter privileged mode on the remote device; if ``ansible_become`` is set to no this key is not applicable. |
|
||||||
|
| ``ansible_network_os`` | yes | os9, null\* | This value is used to load the correct terminal and cliconf plugins to communicate with the remote device. |
|
||||||
|
|
||||||
|
> **NOTE**: Asterisk (\*) denotes the default value if none is specified.
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
|
The *os9_bgp* role is built on modules included in the core Ansible code. These modules were added in Ansible version 2.2.0.
|
||||||
|
|
||||||
|
Example playbook
|
||||||
|
----------------
|
||||||
|
|
||||||
|
This example uses the *os9_bgp* role to configure the BGP network and neighbors. It creates a *hosts* file with the switch details, a *host_vars* file with connection variables and the corresponding role variables.
|
||||||
|
|
||||||
|
When *os9_cfg_generate* is set to true, the variable generates the configuration commands as a .part file in *build_dir* path. By default, the variable is set to false. This example writes a simple playbook that only references the *os9_bgp* role. The sample host_vars given below is for os9.
|
||||||
|
|
||||||
|
**Sample hosts file**
|
||||||
|
|
||||||
|
leaf1 ansible_host= <ip_address>
|
||||||
|
|
||||||
|
**Sample host_vars/leaf1**
|
||||||
|
|
||||||
|
hostname: leaf1
|
||||||
|
ansible_become: yes
|
||||||
|
ansible_become_method: xxxxx
|
||||||
|
ansible_become_pass: xxxxx
|
||||||
|
ansible_ssh_user: xxxxx
|
||||||
|
ansible_ssh_pass: xxxxx
|
||||||
|
ansible_network_os: dellemc.os9.os9
|
||||||
|
build_dir: ../temp/os9
|
||||||
|
|
||||||
|
os9_bgp:
|
||||||
|
asn: 11
|
||||||
|
router_id: 192.168.3.100
|
||||||
|
maxpath_ibgp: 2
|
||||||
|
maxpath_ebgp: 2
|
||||||
|
graceful_restart: true
|
||||||
|
best_path:
|
||||||
|
as_path: ignore
|
||||||
|
ignore_router_id: true
|
||||||
|
med:
|
||||||
|
- attribute: confed
|
||||||
|
state: present
|
||||||
|
- attribute: missing-as-best
|
||||||
|
state: present
|
||||||
|
ipv4_network:
|
||||||
|
- address: 102.1.1.0/30
|
||||||
|
state: present
|
||||||
|
ipv6_network:
|
||||||
|
- address: "2001:4898:5808:ffa0::/126"
|
||||||
|
state: present
|
||||||
|
neighbor:
|
||||||
|
- ip: 192.168.10.2
|
||||||
|
type: ipv4
|
||||||
|
remote_asn: 12
|
||||||
|
timer: 5 10
|
||||||
|
adv_interval: 40
|
||||||
|
fall_over: present
|
||||||
|
default_originate: False
|
||||||
|
peergroup: per
|
||||||
|
peergroup_state: present
|
||||||
|
sender_loop_detect: false
|
||||||
|
src_loopback: 1
|
||||||
|
src_loopback_state: present
|
||||||
|
distribute_list:
|
||||||
|
in: aa
|
||||||
|
in_state: present
|
||||||
|
ebgp_multihop: 25
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- ip: 2001:4898:5808:ffa2::1
|
||||||
|
type: ipv6
|
||||||
|
remote_asn: 14
|
||||||
|
peergroup: per
|
||||||
|
peergroup_state: present
|
||||||
|
distribute_list:
|
||||||
|
in: aa
|
||||||
|
in_state: present
|
||||||
|
src_loopback: 0
|
||||||
|
src_loopback_state: present
|
||||||
|
ebgp_multihop: 255
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
- name: peer1
|
||||||
|
type: peergroup
|
||||||
|
remote_asn: 14
|
||||||
|
distribute_list:
|
||||||
|
in: an
|
||||||
|
in_state: present
|
||||||
|
out: bb
|
||||||
|
out_state: present
|
||||||
|
passive: True
|
||||||
|
subnet: 10.128.4.192/27
|
||||||
|
subnet_state: present
|
||||||
|
state: present
|
||||||
|
- ip: 172.20.12.1
|
||||||
|
description: O_site2-spine1
|
||||||
|
type: ipv4
|
||||||
|
remote_asn: 64640
|
||||||
|
fall_over: present
|
||||||
|
ebgp_multihop: 4
|
||||||
|
src_loopback: 1
|
||||||
|
adv_interval: 1
|
||||||
|
timer: 3 9
|
||||||
|
send_community:
|
||||||
|
- type: extended
|
||||||
|
address_family:
|
||||||
|
- type: ipv4
|
||||||
|
activate: falsesrc_loopback
|
||||||
|
state: present
|
||||||
|
- type: l2vpn
|
||||||
|
activate: true
|
||||||
|
state: present
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
redistribute:
|
||||||
|
- route_type: static
|
||||||
|
route_map_name: aa
|
||||||
|
state: present
|
||||||
|
address_type: ipv4
|
||||||
|
- route_type: connected
|
||||||
|
address_type: ipv6
|
||||||
|
state: present
|
||||||
|
state: present
|
||||||
|
|
||||||
|
**Simple playbook to configure BGP - leaf.yaml**
|
||||||
|
|
||||||
|
- hosts: leaf1
|
||||||
|
roles:
|
||||||
|
- dellemc.os9.os9_bgp
|
||||||
|
|
||||||
|
**Run**
|
||||||
|
|
||||||
|
ansible-playbook -i hosts leaf.yaml
|
||||||
|
|
||||||
|
(c) 2017-2020 Dell Inc. or its subsidiaries. All Rights Reserved.
|
2
roles/os9_bgp/defaults/main.yml
Normal file
2
roles/os9_bgp/defaults/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
# defaults file for dellemc.os9.os9_bgp
|
2
roles/os9_bgp/handlers/main.yml
Normal file
2
roles/os9_bgp/handlers/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
# handlers file for dellemc.os9.os9_bgp
|
19
roles/os9_bgp/meta/main.yml
Normal file
19
roles/os9_bgp/meta/main.yml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# Copyright (c) 2017-2020 Dell Inc. or its subsidiaries. All Rights Reserved.
|
||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Dell EMC Networking Engineering
|
||||||
|
description: The os9_bgp role facilitates the configuration of BGP attributes in devices running Dell EMC Networking Operating Systems.
|
||||||
|
company: Dell Inc
|
||||||
|
license: Apache 2.0
|
||||||
|
min_ansible_version: 2.2
|
||||||
|
|
||||||
|
platforms:
|
||||||
|
- name: os9
|
||||||
|
|
||||||
|
galaxy_tags:
|
||||||
|
- networking
|
||||||
|
- dell
|
||||||
|
- emc
|
||||||
|
- dellemc
|
||||||
|
- os9
|
||||||
|
|
16
roles/os9_bgp/tasks/main.yml
Normal file
16
roles/os9_bgp/tasks/main.yml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
# tasks file for os9
|
||||||
|
- name: "Generating BGP configuration for os9"
|
||||||
|
template:
|
||||||
|
src: os9_bgp.j2
|
||||||
|
dest: "{{ build_dir }}/bgp9_{{ hostname }}.conf.part"
|
||||||
|
when: (ansible_network_os is defined and ansible_network_os == "dellemc.os9.os9") and ((os9_cfg_generate | default('False')) | bool)
|
||||||
|
# notify: save config os9
|
||||||
|
register: generate_output
|
||||||
|
|
||||||
|
- name: "Provisioning BGP configuration for os9"
|
||||||
|
os9_config:
|
||||||
|
src: os9_bgp.j2
|
||||||
|
when: (ansible_network_os is defined and ansible_network_os == "dellemc.os9.os9")
|
||||||
|
# notify: save config os9
|
||||||
|
register: output
|
351
roles/os9_bgp/templates/os9_bgp.j2
Normal file
351
roles/os9_bgp/templates/os9_bgp.j2
Normal file
|
@ -0,0 +1,351 @@
|
||||||
|
#jinja2: trim_blocks: True, lstrip_blocks: True
|
||||||
|
{##########################################
|
||||||
|
Purpose:
|
||||||
|
Configure BGP commands for os9 Devices
|
||||||
|
os9_bgp:
|
||||||
|
asn: 12
|
||||||
|
router_id:
|
||||||
|
maxpath_ibgp: 2
|
||||||
|
maxpath_ebgp: 2
|
||||||
|
best_path:
|
||||||
|
as_path: ignore
|
||||||
|
as_path_state: present
|
||||||
|
ignore_router_id: true
|
||||||
|
med:
|
||||||
|
- attribute: confed
|
||||||
|
state: present
|
||||||
|
ipv4_network:
|
||||||
|
- address: 101.1.1.0/30
|
||||||
|
state: present
|
||||||
|
ipv6_network:
|
||||||
|
- address: "2001:4898:5808:ffa0::/126"
|
||||||
|
state: present
|
||||||
|
neighbor:
|
||||||
|
- type: ipv4
|
||||||
|
remote_asn: 11
|
||||||
|
ip: 192.168.11.1
|
||||||
|
admin: up
|
||||||
|
sender_loop_detect: false
|
||||||
|
src_loopback: 0
|
||||||
|
src_loopback_state: present
|
||||||
|
ebgp_multihop: 255
|
||||||
|
distribute_list:
|
||||||
|
in: aa
|
||||||
|
in_state: present
|
||||||
|
out: aa
|
||||||
|
out_state: present
|
||||||
|
state: present
|
||||||
|
- type: ipv6
|
||||||
|
remote_asn: 14
|
||||||
|
ip: 2001:4898:5808:ffa2::1
|
||||||
|
sender_loop_detect: false
|
||||||
|
src_loopback: 0
|
||||||
|
src_loopback_state: present
|
||||||
|
state: present
|
||||||
|
- type: peer_group
|
||||||
|
name: peer1
|
||||||
|
remote_asn: 6
|
||||||
|
subnet: 10.128.3.192/27
|
||||||
|
subnet_state: present
|
||||||
|
admin: up
|
||||||
|
default_originate: true
|
||||||
|
sender_loop_detect: false
|
||||||
|
src_loopback: 1
|
||||||
|
src_loopback_state: present
|
||||||
|
ebgp_multihop: 255
|
||||||
|
state: present
|
||||||
|
redistribute:
|
||||||
|
- route_type: static
|
||||||
|
state: present
|
||||||
|
state: present
|
||||||
|
################################}
|
||||||
|
{% if os9_bgp is defined and os9_bgp%}
|
||||||
|
{% set bgp_vars = os9_bgp %}
|
||||||
|
|
||||||
|
{% if bgp_vars.asn is defined and bgp_vars.asn %}
|
||||||
|
{% if bgp_vars.state is defined and bgp_vars.state == "absent" %}
|
||||||
|
no router bgp {{ bgp_vars.asn }}
|
||||||
|
{% else %}
|
||||||
|
{# Add Feature to the switch #}
|
||||||
|
router bgp {{ bgp_vars.asn }}
|
||||||
|
{% if bgp_vars.router_id is defined %}
|
||||||
|
{% if bgp_vars.router_id %}
|
||||||
|
bgp router-id {{ bgp_vars.router_id }}
|
||||||
|
{% else %}
|
||||||
|
no bgp router-id
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if bgp_vars.maxpath_ebgp is defined %}
|
||||||
|
{% if bgp_vars.maxpath_ebgp %}
|
||||||
|
maximum-paths ebgp {{ bgp_vars.maxpath_ebgp }}
|
||||||
|
{% else %}
|
||||||
|
no maximum-paths ebgp
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if bgp_vars.maxpath_ibgp is defined %}
|
||||||
|
{% if bgp_vars.maxpath_ibgp %}
|
||||||
|
maximum-paths ibgp {{ bgp_vars.maxpath_ibgp }}
|
||||||
|
{% else %}
|
||||||
|
no maximum-paths ibgp
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if bgp_vars.graceful_restart is defined and bgp_vars.graceful_restart %}
|
||||||
|
{% if bgp_vars.graceful_restart.state is defined and bgp_vars.graceful_restart.state == "present" %}
|
||||||
|
bgp graceful-restart
|
||||||
|
{% else %}
|
||||||
|
no bgp graceful-restart
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if bgp_vars.best_path is defined and bgp_vars.best_path %}
|
||||||
|
{% if bgp_vars.best_path.as_path is defined and bgp_vars.best_path.as_path %}
|
||||||
|
{% if bgp_vars.best_path.as_path_state is defined and bgp_vars.best_path.as_path_state == "absent" %}
|
||||||
|
no bgp bestpath as-path {{ bgp_vars.best_path.as_path }}
|
||||||
|
{% else %}
|
||||||
|
bgp bestpath as-path {{ bgp_vars.best_path.as_path }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if bgp_vars.best_path.ignore_router_id is defined %}
|
||||||
|
{% if bgp_vars.best_path.ignore_router_id %}
|
||||||
|
bgp bestpath router-id ignore
|
||||||
|
{% else %}
|
||||||
|
no bgp bestpath router-id ignore
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if bgp_vars.best_path.med is defined and bgp_vars.best_path.med %}
|
||||||
|
{% for med in bgp_vars.best_path.med %}
|
||||||
|
{% if med.attribute is defined and med.attribute %}
|
||||||
|
{% if med.state is defined and med.state == "absent" %}
|
||||||
|
no bgp bestpath med {{ med.attribute }}
|
||||||
|
{% else %}
|
||||||
|
bgp bestpath med {{ med.attribute }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if bgp_vars.ipv4_network is defined and bgp_vars.ipv4_network %}
|
||||||
|
{% for net in bgp_vars.ipv4_network %}
|
||||||
|
{# remove BGP network announcement #}
|
||||||
|
{% if net.address is defined and net.address %}
|
||||||
|
{% if net.state is defined and net.state == "absent" %}
|
||||||
|
no network {{ net.address }}
|
||||||
|
{# Add BGP network announcement #}
|
||||||
|
{% else %}
|
||||||
|
network {{ net.address }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if bgp_vars.ipv6_network is defined and bgp_vars.ipv6_network %}
|
||||||
|
address-family ipv6 unicast
|
||||||
|
{% for net in bgp_vars.ipv6_network %}
|
||||||
|
{% if net.address is defined and net.address %}
|
||||||
|
{% if net.state is defined and net.state == "absent" %}
|
||||||
|
no network {{ net.address }}
|
||||||
|
{% else %}
|
||||||
|
network {{ net.address }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
exit-address-family
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if bgp_vars.neighbor is defined and bgp_vars.neighbor %}
|
||||||
|
{% for neighbor in bgp_vars.neighbor %}
|
||||||
|
{% if neighbor.type is defined %}
|
||||||
|
{% if neighbor.type == "ipv4" or neighbor.type =="ipv6" %}
|
||||||
|
{% if neighbor.ip is defined and neighbor.ip %}
|
||||||
|
{% set tag_or_ip = neighbor.ip %}
|
||||||
|
{% if neighbor.remote_asn is defined and neighbor.remote_asn %}
|
||||||
|
{% if neighbor.state is defined and neighbor.state == "absent" %}
|
||||||
|
no neighbor {{ tag_or_ip }} remote-as {{ neighbor.remote_asn }}
|
||||||
|
{% if neighbor.peergroup is defined and neighbor.peergroup %}
|
||||||
|
{% if neighbor.peergroup_state is defined and neighbor.peergroup_state == "absent" %}
|
||||||
|
no neighbor {{ tag_or_ip }} peer-group {{ neighbor.peergroup }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if neighbor.type == "ipv6" %}
|
||||||
|
address-family ipv6 unicast
|
||||||
|
no neighbor {{ tag_or_ip }} activate
|
||||||
|
exit-address-family
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
neighbor {{ tag_or_ip }} remote-as {{ neighbor.remote_asn }}
|
||||||
|
{% if neighbor.peergroup is defined and neighbor.peergroup %}
|
||||||
|
{% if neighbor.peergroup_state is defined and neighbor.peergroup_state == "absent" %}
|
||||||
|
no neighbor {{ tag_or_ip }} peer-group {{ neighbor.peergroup }}
|
||||||
|
{% else %}
|
||||||
|
neighbor {{ tag_or_ip }} peer-group {{ neighbor.peergroup }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if neighbor.type == "ipv6" %}
|
||||||
|
address-family ipv6 unicast
|
||||||
|
neighbor {{ tag_or_ip }} activate
|
||||||
|
exit-address-family
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% elif neighbor.type == "peergroup" %}
|
||||||
|
{% if neighbor.name is defined and neighbor.name %}
|
||||||
|
{% set tag_or_ip = neighbor.name %}
|
||||||
|
{% if neighbor.state is defined and neighbor.state == "absent" %}
|
||||||
|
no neighbor {{ tag_or_ip }} peer-group
|
||||||
|
{% else %}
|
||||||
|
{% if neighbor.passive is defined and neighbor.passive %}
|
||||||
|
neighbor {{ tag_or_ip }} peer-group passive
|
||||||
|
{% if neighbor.subnet is defined and neighbor.subnet %}
|
||||||
|
{% if neighbor.subnet_state is defined and neighbor.subnet_state == "absent" %}
|
||||||
|
no neighbor {{ tag_or_ip }} subnet {{ neighbor.subnet }}
|
||||||
|
{% else %}
|
||||||
|
neighbor {{ tag_or_ip }} subnet {{ neighbor.subnet }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
neighbor {{ tag_or_ip }} peer-group
|
||||||
|
{% endif %}
|
||||||
|
{% if neighbor.remote_asn is defined and neighbor.remote_asn %}
|
||||||
|
{% if neighbor.remote_asn_state is defined and neighbor.remote_asn_state == "absent" %}
|
||||||
|
no neighbor {{ tag_or_ip }} remote-as {{ neighbor.remote_asn }}
|
||||||
|
{% else %}
|
||||||
|
neighbor {{ tag_or_ip }} remote-as {{ neighbor.remote_asn }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if tag_or_ip is defined and tag_or_ip %}
|
||||||
|
{% if (neighbor.state is not defined) or (neighbor.state is defined and not neighbor.state == "absent") %}
|
||||||
|
{% if neighbor.timer is defined %}
|
||||||
|
{% if neighbor.timer %}
|
||||||
|
neighbor {{ tag_or_ip }} timers {{ neighbor.timer }}
|
||||||
|
{% else %}
|
||||||
|
no neighbor {{ tag_or_ip }} timers
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if neighbor.default_originate is defined %}
|
||||||
|
{% if neighbor.default_originate %}
|
||||||
|
neighbor {{ tag_or_ip }} default-originate
|
||||||
|
{% else %}
|
||||||
|
no neighbor {{ tag_or_ip }} default-originate
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if neighbor.sender_loop_detect is defined %}
|
||||||
|
{% if neighbor.sender_loop_detect %}
|
||||||
|
neighbor {{ tag_or_ip }} sender-side-loop-detection
|
||||||
|
{% else %}
|
||||||
|
no neighbor {{ tag_or_ip }} sender-side-loop-detection
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if neighbor.src_loopback is defined and neighbor.src_loopback|int(-1) != -1 %}
|
||||||
|
{% if neighbor.src_loopback_state is defined and neighbor.src_loopback_state == "absent" %}
|
||||||
|
no neighbor {{ tag_or_ip }} update-source Loopback {{neighbor.src_loopback }}
|
||||||
|
{% else %}
|
||||||
|
neighbor {{ tag_or_ip }} update-source Loopback {{ neighbor.src_loopback }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if neighbor.ebgp_multihop is defined %}
|
||||||
|
{% if neighbor.ebgp_multihop %}
|
||||||
|
neighbor {{ tag_or_ip }} ebgp-multihop {{ neighbor.ebgp_multihop }}
|
||||||
|
{% else %}
|
||||||
|
no neighbor {{ tag_or_ip }} ebgp-multihop
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if neighbor.distribute_list is defined and neighbor.distribute_list %}
|
||||||
|
{% if neighbor.distribute_list.in is defined and neighbor.distribute_list.in %}
|
||||||
|
{% if neighbor.distribute_list.in_state is defined and neighbor.distribute_list.in_state == "absent" %}
|
||||||
|
no neighbor {{ tag_or_ip }} distribute-list {{ neighbor.distribute_list.in }} in
|
||||||
|
{% else %}
|
||||||
|
neighbor {{ tag_or_ip }} distribute-list {{ neighbor.distribute_list.in }} in
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if neighbor.distribute_list.out is defined and neighbor.distribute_list.out %}
|
||||||
|
{% if neighbor.distribute_list.out_state is defined and neighbor.distribute_list.out_state == "absent" %}
|
||||||
|
no neighbor {{ tag_or_ip }} distribute-list {{ neighbor.distribute_list.out }} out
|
||||||
|
{% else %}
|
||||||
|
neighbor {{ tag_or_ip }} distribute-list {{ neighbor.distribute_list.out }} out
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if neighbor.admin is defined and (neighbor.admin == "up" or neighbor.admin == "present") %}
|
||||||
|
neighbor {{ tag_or_ip }} no shutdown
|
||||||
|
{% else %}
|
||||||
|
neighbor {{ tag_or_ip }} shutdown
|
||||||
|
{% endif %}
|
||||||
|
{% if neighbor.adv_interval is defined %}
|
||||||
|
{% if neighbor.adv_interval %}
|
||||||
|
neighbor {{ tag_or_ip }} advertisement-interval {{ neighbor.adv_interval }}
|
||||||
|
{% else %}
|
||||||
|
no neighbor {{ tag_or_ip }} advertisement-interval
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if neighbor.fall_over is defined and neighbor.fall_over == "present" %}
|
||||||
|
neighbor {{ tag_or_ip }} fall-over
|
||||||
|
{% elif neighbor.fall_over is defined and neighbor.fall_over == "absent" %}
|
||||||
|
no neighbor {{ tag_or_ip }} fall-over
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if bgp_vars.redistribute is defined and bgp_vars.redistribute %}
|
||||||
|
{% for route in bgp_vars.redistribute %}
|
||||||
|
{% if route.route_type is defined and route.route_type %}
|
||||||
|
{% if route.address_type is defined and route.address_type %}
|
||||||
|
{% if route.address_type == "ipv6" %}
|
||||||
|
address-family {{ route.address_type }} unicast
|
||||||
|
{% if route.state is defined and route.state == "absent" %}
|
||||||
|
no redistribute {{ route.route_type }}
|
||||||
|
{% else %}
|
||||||
|
{% if route.route_map is defined %}
|
||||||
|
{% if route.route_map == "present" %}
|
||||||
|
{% if route.route_map_name is defined and route.route_map_name %}
|
||||||
|
redistribute {{ route.route_type }} route-map {{ route.route_map_name }}
|
||||||
|
{% else %}
|
||||||
|
redistribute {{ route.route_type }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if route.route_map_name is defined and route.route_map_name %}
|
||||||
|
no redistribute {{ route.route_type }} route-map {{ route.route_map_name }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
redistribute {{ route.route_type }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
exit-address-family
|
||||||
|
{% else %}
|
||||||
|
{% if route.state is defined and route.state == "absent" %}
|
||||||
|
no redistribute {{ route.route_type }}
|
||||||
|
{% else %}
|
||||||
|
{% if route.route_map is defined %}
|
||||||
|
{% if route.route_map == "present" %}
|
||||||
|
{% if route.route_map_name is defined and route.route_map_name %}
|
||||||
|
redistribute {{ route.route_type }} route-map {{ route.route_map_name }}
|
||||||
|
{% else %}
|
||||||
|
redistribute {{ route.route_type }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if route.route_map_name is defined and route.route_map_name %}
|
||||||
|
no redistribute {{ route.route_type }} route-map {{ route.route_map_name }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
redistribute {{ route.route_type }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
20
roles/os9_bgp/tests/inventory.yaml
Normal file
20
roles/os9_bgp/tests/inventory.yaml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
spine1 ansible_host=100.94.210.44
|
||||||
|
spine2 ansible_host=10.11.182.26
|
||||||
|
leaf1 ansible_host=10.11.182.27
|
||||||
|
leaf2 ansible_host=10.11.182.28
|
||||||
|
leaf3 ansible_host=10.11.182.29
|
||||||
|
leaf4 ansible_host=10.11.182.30
|
||||||
|
|
||||||
|
[spine]
|
||||||
|
spine1
|
||||||
|
spine2
|
||||||
|
|
||||||
|
[leaf]
|
||||||
|
leaf1
|
||||||
|
leaf2
|
||||||
|
leaf3
|
||||||
|
leaf4
|
||||||
|
|
||||||
|
[datacenter:children]
|
||||||
|
spine
|
||||||
|
leaf
|
97
roles/os9_bgp/tests/main.os9.yaml
Normal file
97
roles/os9_bgp/tests/main.os9.yaml
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
---
|
||||||
|
# vars file for dellemc.os9.os9_bgp,
|
||||||
|
# below gives a sample configuration
|
||||||
|
# Sample variables for OS9 device
|
||||||
|
os9_bgp:
|
||||||
|
asn: 11
|
||||||
|
router_id: 192.168.3.100
|
||||||
|
maxpath_ibgp: 2
|
||||||
|
maxpath_ebgp: 2
|
||||||
|
best_path:
|
||||||
|
as_path: ignore
|
||||||
|
as_path_state: absent
|
||||||
|
ignore_router_id: true
|
||||||
|
med:
|
||||||
|
- attribute: confed
|
||||||
|
state: present
|
||||||
|
- attribute: missing-as-best
|
||||||
|
state: present
|
||||||
|
ipv4_network:
|
||||||
|
- address: 102.1.1.0/30
|
||||||
|
state: present
|
||||||
|
ipv6_network:
|
||||||
|
- address: "2001:4898:5808:ffa0::/126"
|
||||||
|
state: present
|
||||||
|
- address: "2001:4898:5808:ffa1::/126"
|
||||||
|
state: present
|
||||||
|
neighbor:
|
||||||
|
- name: per
|
||||||
|
type: peergroup
|
||||||
|
remote_asn: 12
|
||||||
|
remote_asn_state: absent
|
||||||
|
default_originate: False
|
||||||
|
src_loopback: 0
|
||||||
|
src_loopback_state: present
|
||||||
|
ebgp_multihop: 255
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: peer1
|
||||||
|
type: peergroup
|
||||||
|
remote_asn: 14
|
||||||
|
distribute_list:
|
||||||
|
in: an
|
||||||
|
in_state: present
|
||||||
|
out: bb
|
||||||
|
out_state: present
|
||||||
|
passive: True
|
||||||
|
subnet: 10.128.4.192/27
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- ip: 192.168.10.2
|
||||||
|
type: ipv4
|
||||||
|
remote_asn: 12
|
||||||
|
timer: 5 10
|
||||||
|
default_originate: False
|
||||||
|
peergroup: per
|
||||||
|
peergroup_state: present
|
||||||
|
distribute_list:
|
||||||
|
in: aa
|
||||||
|
in_state: present
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- ip: 192.168.13.3
|
||||||
|
type: ipv4
|
||||||
|
remote_asn: 13
|
||||||
|
sender_loop_detect: false
|
||||||
|
src_loopback: 1
|
||||||
|
src_loopback_state: present
|
||||||
|
distribute_list:
|
||||||
|
in: aa
|
||||||
|
in_state: present
|
||||||
|
out: aa
|
||||||
|
out_state: present
|
||||||
|
ebgp_multihop: 25
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- ip: 2001:4898:5808:ffa2::1
|
||||||
|
type: ipv6
|
||||||
|
remote_asn: 14
|
||||||
|
peergroup: per
|
||||||
|
peergroup_state: present
|
||||||
|
distribute_list:
|
||||||
|
in: aa
|
||||||
|
in_state: present
|
||||||
|
src_loopback: 0
|
||||||
|
src_loopback_state: present
|
||||||
|
ebgp_multihop: 255
|
||||||
|
admin: up
|
||||||
|
state: present
|
||||||
|
redistribute:
|
||||||
|
- route_type: static
|
||||||
|
state: present
|
||||||
|
address_type: ipv4
|
||||||
|
- route_type: connected
|
||||||
|
address_type: ipv6
|
||||||
|
state: present
|
||||||
|
state: present
|
5
roles/os9_bgp/tests/test.yaml
Normal file
5
roles/os9_bgp/tests/test.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
- hosts: datacenter
|
||||||
|
connection: network_cli
|
||||||
|
roles:
|
||||||
|
- dellemc.os9.os9_bgp
|
2
roles/os9_bgp/vars/main.yml
Normal file
2
roles/os9_bgp/vars/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
# vars file for dellemc.os9.os9_bgp
|
201
roles/os9_copy_config/LICENSE
Normal file
201
roles/os9_copy_config/LICENSE
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright (c) 2020, Dell EMC. All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
136
roles/os9_copy_config/README.md
Normal file
136
roles/os9_copy_config/README.md
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
Copy-config role
|
||||||
|
================
|
||||||
|
|
||||||
|
This role is used to push the backup running configuration into a Dell EMC Networking device running OS9, and merges the configuration in the template file with the running configuration of the device.
|
||||||
|
|
||||||
|
The copy_config role requires an SSH connection for connectivity to a Dell EMC Networking device. You can use any of the built-in OS connection variables .
|
||||||
|
|
||||||
|
|
||||||
|
Role variables
|
||||||
|
--------------
|
||||||
|
|
||||||
|
- No predefined variables are part of this role
|
||||||
|
- Use *host_vars* or *group_vars* as part of the template file
|
||||||
|
- Configuration file is host-specific
|
||||||
|
- Copy the host-specific configuration to the respective file under the template directory in *<host_name>.j2* format
|
||||||
|
- Variables and values are case-sensitive
|
||||||
|
|
||||||
|
Connection variables
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Ansible Dell EMC Networking roles require connection information to establish communication with the nodes in your inventory. This information can exist in the Ansible *group_vars* or *host_vars* directories, or in the playbook itself.
|
||||||
|
|
||||||
|
| Key | Required | Choices | Description |
|
||||||
|
|-------------|----------|------------|-----------------------------------------------------|
|
||||||
|
| ``ansible_host`` | yes | | Specifies the hostname or address for connecting to the remote device over the specified transport |
|
||||||
|
| ``ansible_port`` | no | | Specifies the port used to build the connection to the remote device; if value is unspecified, the ANSIBLE_REMOTE_PORT option is used; it defaults to 22 |
|
||||||
|
| ``ansible_ssh_user`` | no | | Specifies the username that authenticates the CLI login for the connection to the remote device; if value is unspecified, the ANSIBLE_REMOTE_USER environment variable value is used |
|
||||||
|
| ``ansible_ssh_pass`` | no | | Specifies the password that authenticates the connection to the remote device. |
|
||||||
|
| ``ansible_become`` | no | yes, no\* | Instructs the module to enter privileged mode on the remote device before sending any commands; if value is unspecified, the ANSIBLE_BECOME environment variable value is used, and the device attempts to execute all commands in non-privileged mode |
|
||||||
|
| ``ansible_become_method`` | no | enable, sudo\* | Instructs the module to allow the become method to be specified for handling privilege escalation; if value is unspecified, the ANSIBLE_BECOME_METHOD environment variable value is used. |
|
||||||
|
| ``ansible_become_pass`` | no | | Specifies the password to use if required to enter privileged mode on the remote device; if ``ansible_become`` is set to no this key is not applicable. |
|
||||||
|
| ``ansible_network_os`` | yes | os9, null\* | This value is used to load the correct terminal and cliconf plugins to communicate with the remote device. |
|
||||||
|
|
||||||
|
> **NOTE**: Asterisk (\*) denotes the default value if none is specified.
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
|
The *os9_copy_config* role is built on modules included in the core Ansible code. These modules were added in Ansible version 2.2.0.
|
||||||
|
|
||||||
|
Example playbook
|
||||||
|
----------------
|
||||||
|
|
||||||
|
This example uses the *os9_copy_config* role to push the configuration file into the device. It creates a *hosts* file with the switch details and corresponding variables. It writes a simple playbook that only references the *os9_copy_config* role. By including the role, you automatically get access to all of the tasks to push configuration file.
|
||||||
|
|
||||||
|
**Sample hosts file**
|
||||||
|
|
||||||
|
leaf1 ansible_host= <ip_address>
|
||||||
|
|
||||||
|
**Sample host_vars/leaf1**
|
||||||
|
|
||||||
|
hostname: leaf1
|
||||||
|
ansible_become: yes
|
||||||
|
ansible_become_method: xxxxx
|
||||||
|
ansible_become_pass: xxxxx
|
||||||
|
ansible_ssh_user: xxxxx
|
||||||
|
ansible_ssh_pass: xxxxx
|
||||||
|
ansible_network_os: dellemc.os9.os9
|
||||||
|
|
||||||
|
# This variable shall be applied in the below jinja template for each host by defining here
|
||||||
|
os9_bgp
|
||||||
|
asn: 64801
|
||||||
|
|
||||||
|
**Sample roles/os9_copy_config/templates/leaf1.j2**
|
||||||
|
|
||||||
|
! Leaf1 BGP profile on Dell OS9 switch
|
||||||
|
snmp-server community public ro
|
||||||
|
hash-algorithm ecmp crc
|
||||||
|
!
|
||||||
|
interface ethernet1/1/1:1
|
||||||
|
no switchport
|
||||||
|
ip address 100.1.1.2/24
|
||||||
|
ipv6 address 2001:100:1:1::2/64
|
||||||
|
mtu 9216
|
||||||
|
no shutdown
|
||||||
|
!
|
||||||
|
interface ethernet1/1/9:1
|
||||||
|
no switchport
|
||||||
|
ip address 100.2.1.2/24
|
||||||
|
ipv6 address 2001:100:2:1::2/64
|
||||||
|
mtu 9216
|
||||||
|
no shutdown
|
||||||
|
!
|
||||||
|
router bgp {{ os9_bgp.asn }}
|
||||||
|
bestpath as-path multipath-relax
|
||||||
|
bestpath med missing-as-worst
|
||||||
|
router-id 100.0.2.1
|
||||||
|
!
|
||||||
|
address-family ipv4 unicast
|
||||||
|
!
|
||||||
|
address-family ipv6 unicast
|
||||||
|
!
|
||||||
|
neighbor 100.1.1.1
|
||||||
|
remote-as 64901
|
||||||
|
no shutdown
|
||||||
|
!
|
||||||
|
neighbor 100.2.1.1
|
||||||
|
remote-as 64901
|
||||||
|
no shutdown
|
||||||
|
!
|
||||||
|
neighbor 2001:100:1:1::1
|
||||||
|
remote-as 64901
|
||||||
|
no shutdown
|
||||||
|
!
|
||||||
|
address-family ipv4 unicast
|
||||||
|
no activate
|
||||||
|
exit
|
||||||
|
!
|
||||||
|
address-family ipv6 unicast
|
||||||
|
activate
|
||||||
|
exit
|
||||||
|
!
|
||||||
|
neighbor 2001:100:2:1::1
|
||||||
|
remote-as 64901
|
||||||
|
no shutdown
|
||||||
|
!
|
||||||
|
address-family ipv4 unicast
|
||||||
|
no activate
|
||||||
|
exit
|
||||||
|
!
|
||||||
|
address-family ipv6 unicast
|
||||||
|
activate
|
||||||
|
exit
|
||||||
|
!
|
||||||
|
|
||||||
|
**Simple playbook to setup to push configuration file into device - leaf.yaml**
|
||||||
|
|
||||||
|
- hosts: leaf1
|
||||||
|
roles:
|
||||||
|
- dellemc.os9.os9_copy_config
|
||||||
|
|
||||||
|
**Run**
|
||||||
|
|
||||||
|
ansible-playbook -i hosts leaf.yaml
|
||||||
|
|
||||||
|
(c) 2020 Dell Inc. or its subsidiaries. All Rights Reserved.
|
2
roles/os9_copy_config/defaults/main.yml
Normal file
2
roles/os9_copy_config/defaults/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
# defaults file for dellemc.os9.os9_copy_config
|
2
roles/os9_copy_config/handlers/main.yml
Normal file
2
roles/os9_copy_config/handlers/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
# handlers file for dellemc.os9.os9_copy_config
|
20
roles/os9_copy_config/meta/main.yml
Normal file
20
roles/os9_copy_config/meta/main.yml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# Copyright (c) 2020 Dell Inc.
|
||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Dell EMC Networking Engineering
|
||||||
|
description: >
|
||||||
|
This role shall be used to push the backup running configuration into the device.
|
||||||
|
This role shall merge the configuration in the template file with the running configuration of the device
|
||||||
|
license: Apache 2.0
|
||||||
|
min_ansible_version: 2.2
|
||||||
|
|
||||||
|
platforms:
|
||||||
|
- name: os9
|
||||||
|
|
||||||
|
galaxy_tags:
|
||||||
|
- networking
|
||||||
|
- dell
|
||||||
|
- emc
|
||||||
|
- dellemc
|
||||||
|
- os9
|
||||||
|
|
7
roles/os9_copy_config/tasks/main.yml
Normal file
7
roles/os9_copy_config/tasks/main.yml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
# tasks file for dellemc.os9.os9_copy_config
|
||||||
|
- name: "Merge the config file to running configuration for OS9"
|
||||||
|
os9_config:
|
||||||
|
src: "{{ hostname }}.j2"
|
||||||
|
when: (ansible_network_os is defined and ansible_network_os == "dellemc.os9.os9")
|
||||||
|
# notify: save config os9
|
3
roles/os9_copy_config/templates/os9_copy_config.j2
Normal file
3
roles/os9_copy_config/templates/os9_copy_config.j2
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
! Version 10.3.0E
|
||||||
|
! Last configuration change at May 09 21:47:35 2017
|
||||||
|
!
|
20
roles/os9_copy_config/tests/inventory.yaml
Normal file
20
roles/os9_copy_config/tests/inventory.yaml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
spine1 ansible_host=100.94.210.44
|
||||||
|
spine2 ansible_host=10.11.182.26
|
||||||
|
leaf1 ansible_host=10.11.182.27
|
||||||
|
leaf2 ansible_host=10.11.182.28
|
||||||
|
leaf3 ansible_host=10.11.182.29
|
||||||
|
leaf4 ansible_host=10.11.182.30
|
||||||
|
|
||||||
|
[spine]
|
||||||
|
spine1
|
||||||
|
spine2
|
||||||
|
|
||||||
|
[leaf]
|
||||||
|
leaf1
|
||||||
|
leaf2
|
||||||
|
leaf3
|
||||||
|
leaf4
|
||||||
|
|
||||||
|
[datacenter:children]
|
||||||
|
spine
|
||||||
|
leaf
|
1
roles/os9_copy_config/tests/main.os9.yaml
Normal file
1
roles/os9_copy_config/tests/main.os9.yaml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
---
|
5
roles/os9_copy_config/tests/test.yaml
Normal file
5
roles/os9_copy_config/tests/test.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
- hosts: localhost
|
||||||
|
connection: network_cli
|
||||||
|
roles:
|
||||||
|
- dellemc.os9.os9_copy_config
|
2
roles/os9_copy_config/vars/main.yml
Normal file
2
roles/os9_copy_config/vars/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
# vars file for dellemc.os9.os9_copy_config
|
201
roles/os9_dcb/LICENSE
Normal file
201
roles/os9_dcb/LICENSE
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright (c) 2020, Dell EMC. All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
138
roles/os9_dcb/README.md
Normal file
138
roles/os9_dcb/README.md
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
DCB role
|
||||||
|
========
|
||||||
|
|
||||||
|
This role facilitates the configuration of data center bridging (DCB). It supports the configuration of the DCB map and the DCB buffer, and assigns them to interfaces. This role is abstracted for Dell EMC platfroms running OS9.
|
||||||
|
|
||||||
|
The DCB role requires an SSH connection for connectivity to a Dell EMC Networking device. You can use any of the built-in OS connection variables .
|
||||||
|
|
||||||
|
|
||||||
|
Role variables
|
||||||
|
--------------
|
||||||
|
|
||||||
|
- Role is abstracted using the *ansible_network_os* variable and can take the dellemc.os9.os9 as a value
|
||||||
|
- If *os9_cfg_generate* is set to true, generates the role configuration commands in a file
|
||||||
|
- Any role variable with a corresponding state variable set to absent negates the configuration of that variable
|
||||||
|
- Setting an empty value for any variable negates the corresponding configuration
|
||||||
|
- Variables and values are case-sensitive
|
||||||
|
|
||||||
|
**os9_dcb keys**
|
||||||
|
|
||||||
|
| Key | Type | Description | Support |
|
||||||
|
|------------|---------------------------|---------------------------------------------------------|-----------------------|
|
||||||
|
| ``dcb_enable`` | boolean: true,false | Enables/disables DCB | os9 |
|
||||||
|
| ``dcb_map`` | list | Configures the DCB map (see ``dcb_map.*``) | os9 |
|
||||||
|
| ``dcb_map.name`` | string (required) | Configures the DCB map name | os9 |
|
||||||
|
| ``dcb_map.priority_group`` | list | Configures the priority-group for the DCB map (see ``priority_group.*``) | os9 |
|
||||||
|
| ``priority_group.pgid`` | integer (required): 0-7 | Configures the priority-group ID | os9 |
|
||||||
|
| ``priority_group.bandwidth`` | integer (required) | Configures the bandwidth percentage for the priority-group | os9 |
|
||||||
|
| ``priority_group.pfc`` | boolean: true,false (required) | Configures PFC on/off for the priorities in the priority-group | os9 |
|
||||||
|
| ``priority_group.state`` | string: absent,present\* | Deletes the priority-group of the DCB map if set to absent | os9 |
|
||||||
|
| ``dcb_map.priority_pgid`` |string (required) | Configures priority to priority-group mapping; value is the PGID of priority groups separated by a space (1 1 2 2 3 3 3 4) | os9 |
|
||||||
|
| ``dcb_map.intf`` | list | Configures the DCB map to the interface (see ``intf.*``) | os9 |
|
||||||
|
| ``intf.name`` | string (required) | Configures the DCB map to the interface with this interface name | os9 |
|
||||||
|
| ``intf.state`` | string: absent,present\* | Deletes the DCB map from the interface if set to absent | os9 |
|
||||||
|
| ``dcb_map.state`` | string: absent,present\* | Deletes the DCB map if set to absent | os9 |
|
||||||
|
| ``dcb_buffer`` | list | Configures the DCB buffer profile (see ``dcb_buffer.*``) | os9 |
|
||||||
|
| ``dcb_buffer.name`` | string (required) | Configures the DCB buffer profile name | os9 |
|
||||||
|
| ``dcb_buffer.description`` | string (required) | Configures a description about the DCB buffer profile | os9 |
|
||||||
|
| ``dcb_buffer.priority_params`` | list | Configures priority flow-control buffer parameters (see ``priority_params.*``)| os9 |
|
||||||
|
| ``priority_params.pgid`` | integer (required): 0-7 | Specifies the priority-group ID | os9 |
|
||||||
|
| ``priority_params.buffer_size`` | int (required) | Configures the ingress buffer size (in KB) of the DCB buffer profile | os9 |
|
||||||
|
| ``priority_params.pause`` | integer | Configures the buffer limit (in KB) for pausing | os9 |
|
||||||
|
| ``priority_params.resume`` | integer | Configures buffer offset limit (in KB) for resume | os9 |
|
||||||
|
| ``priority_params.state`` | string: absent,present\* | Deletes the priority flow parameters of the DCB buffer if set to absent | os9 |
|
||||||
|
| ``dcb_buffer.intf`` | list | Configures the DCB buffer to the interface (see ``intf.*``) | os9 |
|
||||||
|
| ``intf.name`` | string (required) | Configures the DCB buffer to the interface with this interface name | os9 |
|
||||||
|
| ``intf.state`` | string: absent,present\* | Deletes the DCB buffer from the interface if set to absent | os9 |
|
||||||
|
| ``dcb_buffer.state`` | string: absent,present\* | Deletes the DCB buffer profile if set to absent | os9 |
|
||||||
|
|
||||||
|
> **NOTE**: Asterisk (\*) denotes the default value if none is specified.
|
||||||
|
|
||||||
|
Connection variables
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Ansible Dell EMC Networking roles require connection information to establish communication with the nodes in your inventory. This information can exist in the Ansible *group_vars* or *host_vars* directories or inventory, or in the playbook itself.
|
||||||
|
|
||||||
|
| Key | Required | Choices | Description |
|
||||||
|
|-------------|----------|------------|-----------------------------------------------------|
|
||||||
|
| ``ansible_host`` | yes | | Specifies the hostname or address for connecting to the remote device over the specified transport |
|
||||||
|
| ``ansible_port`` | no | | Specifies the port used to build the connection to the remote device; if value is unspecified, the ANSIBLE_REMOTE_PORT option is used; it defaults to 22 |
|
||||||
|
| ``ansible_ssh_user`` | no | | Specifies the username that authenticates the CLI login for the connection to the remote device; if value is unspecified, the ANSIBLE_REMOTE_USER environment variable value is used |
|
||||||
|
| ``ansible_ssh_pass`` | no | | Specifies the password that authenticates the connection to the remote device. |
|
||||||
|
| ``ansible_become`` | no | yes, no\* | Instructs the module to enter privileged mode on the remote device before sending any commands; if value is unspecified, the ANSIBLE_BECOME environment variable value is used, and the device attempts to execute all commands in non-privileged mode |
|
||||||
|
| ``ansible_become_method`` | no | enable, sudo\* | Instructs the module to allow the become method to be specified for handling privilege escalation; if value is unspecified, the ANSIBLE_BECOME_METHOD environment variable value is used. |
|
||||||
|
| ``ansible_become_pass`` | no | | Specifies the password to use if required to enter privileged mode on the remote device; if ``ansible_become`` is set to no this key is not applicable. |
|
||||||
|
| ``ansible_network_os`` | yes | os9, null\* | This value is used to load the correct terminal and cliconf plugins to communicate with the remote device. |
|
||||||
|
|
||||||
|
> **NOTE**: Asterisk (\*) denotes the default value if none is specified.
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
|
||||||
|
The *os9_dcb* role is built on modules included in the core Ansible code. These modules were added in Ansible version 2.2.0.
|
||||||
|
|
||||||
|
Example playbook
|
||||||
|
----------------
|
||||||
|
|
||||||
|
This example uses the *os9_dcb* role to completely configure DCB map and DCB buffer profiles and assigns it to interfaces. The example creates a *hosts* file with the switch details and corresponding variables. The hosts file should define the *ansible_network_os* variable with corresponding Dell EMC networking OS name.
|
||||||
|
|
||||||
|
When *os9_cfg_generate* is set to true, the variable generates the configuration commands as a .part file in *build_dir* path. By default it is set to false. It writes a simple playbook that only references the *os9_dcb* role.
|
||||||
|
|
||||||
|
**Sample hosts file**
|
||||||
|
|
||||||
|
leaf1 ansible_host= <ip_address>
|
||||||
|
|
||||||
|
**Sample host_vars/leaf1**
|
||||||
|
|
||||||
|
hostname: leaf1
|
||||||
|
ansible_become: yes
|
||||||
|
ansible_become_method: xxxxx
|
||||||
|
ansible_become_pass: xxxxx
|
||||||
|
ansible_ssh_user: xxxxx
|
||||||
|
ansible_ssh_pass: xxxxx
|
||||||
|
ansible_network_os: dellemc.os9.os9
|
||||||
|
build_dir: ../temp/os9
|
||||||
|
os9_dcb:
|
||||||
|
dcb_map:
|
||||||
|
- name: test
|
||||||
|
priority_pgid: 0 0 0 3 3 3 3 0
|
||||||
|
priority_group:
|
||||||
|
- pgid: 0
|
||||||
|
bandwidth: 20
|
||||||
|
pfc: true
|
||||||
|
state: present
|
||||||
|
- pgid: 3
|
||||||
|
bandwidth: 80
|
||||||
|
pfc: true
|
||||||
|
state: present
|
||||||
|
intf:
|
||||||
|
- name: fortyGigE 1/8
|
||||||
|
state: present
|
||||||
|
- name: fortyGigE 1/9
|
||||||
|
state: present
|
||||||
|
state: present
|
||||||
|
dcb_buffer:
|
||||||
|
- name: buffer
|
||||||
|
description:
|
||||||
|
priority_params:
|
||||||
|
- pgid: 0
|
||||||
|
buffer_size: 5550
|
||||||
|
pause: 40
|
||||||
|
resume: 40
|
||||||
|
state: present
|
||||||
|
intf:
|
||||||
|
- name: fortyGigE 1/8
|
||||||
|
state: present
|
||||||
|
state: present
|
||||||
|
|
||||||
|
**Simple playbook to setup system - leaf.yaml**
|
||||||
|
|
||||||
|
- hosts: leaf1
|
||||||
|
roles:
|
||||||
|
- dellemc.os9.os9
|
||||||
|
|
||||||
|
**Run**
|
||||||
|
|
||||||
|
ansible-playbook -i hosts leaf.yaml
|
||||||
|
|
||||||
|
(c) 2020 Dell Inc. or its subsidiaries. All Rights Reserved.
|
2
roles/os9_dcb/defaults/main.yml
Normal file
2
roles/os9_dcb/defaults/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
# defaults file for dellemc.os9.os9_dcb
|
2
roles/os9_dcb/handlers/main.yml
Normal file
2
roles/os9_dcb/handlers/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
# handlers file for dellemc.os9.os9_dcb
|
17
roles/os9_dcb/meta/main.yml
Normal file
17
roles/os9_dcb/meta/main.yml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Copyright (c) 2020 Dell Inc.
|
||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Dell EMC Networking Engineering
|
||||||
|
description: The os9_dcb role facilitates the configuration of Data Center Bridging (DCB) attributes in devices running Dell EMC Networking Operating Systems.
|
||||||
|
license: Apache 2.0
|
||||||
|
min_ansible_version: 2.2
|
||||||
|
|
||||||
|
platforms:
|
||||||
|
- name: os9
|
||||||
|
|
||||||
|
galaxy_tags:
|
||||||
|
- networking
|
||||||
|
- dell
|
||||||
|
- emc
|
||||||
|
- dellemc
|
||||||
|
- os9
|
16
roles/os9_dcb/tasks/main.yml
Normal file
16
roles/os9_dcb/tasks/main.yml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
# tasks file for os9
|
||||||
|
- name: "Generating DCB configuration for os9"
|
||||||
|
template:
|
||||||
|
src: os9_dcb.j2
|
||||||
|
dest: "{{ build_dir }}/dcb9_{{ hostname }}.conf.part"
|
||||||
|
when: (ansible_network_os is defined and ansible_network_os == "dellemc.os9.os9") and ((os9_cfg_generate | default('False')) | bool)
|
||||||
|
# notify: save config os9
|
||||||
|
register: generate_output
|
||||||
|
|
||||||
|
- name: "Provisioning DCB configuration for os9"
|
||||||
|
os9_config:
|
||||||
|
src: os9_dcb.j2
|
||||||
|
when: (ansible_network_os is defined and ansible_network_os == "dellemc.os9.os9")
|
||||||
|
# notify: save config os9
|
||||||
|
register: output
|
216
roles/os9_dcb/templates/os9_dcb.j2
Normal file
216
roles/os9_dcb/templates/os9_dcb.j2
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
#jinja2: trim_blocks: True,lstrip_blocks: True
|
||||||
|
{################################
|
||||||
|
Purpose:
|
||||||
|
Configure DCB commands for os9 Devices
|
||||||
|
os9_dcb:
|
||||||
|
dcb_enable: true
|
||||||
|
dcb_map:
|
||||||
|
- name: test
|
||||||
|
priority_pgid: 0 0 0 3 3 3 0 3
|
||||||
|
priority_group:
|
||||||
|
- pgid: 0
|
||||||
|
bandwidth: 20
|
||||||
|
pfc: true
|
||||||
|
state: present
|
||||||
|
- pgid: 3
|
||||||
|
bandwidth: 20
|
||||||
|
pfc: true
|
||||||
|
state: present
|
||||||
|
intf:
|
||||||
|
- name: fortyGigE 1/8
|
||||||
|
state: present
|
||||||
|
- name: fortyGigE 1/9
|
||||||
|
state: present
|
||||||
|
state: present
|
||||||
|
dcb_buffer:
|
||||||
|
- name: buffer
|
||||||
|
description:
|
||||||
|
priority_params:
|
||||||
|
- pgid: 0
|
||||||
|
buffer_size: 5550
|
||||||
|
pause: 40
|
||||||
|
resume: 40
|
||||||
|
state: present
|
||||||
|
intf:
|
||||||
|
- name: fortyGigE 1/6
|
||||||
|
state: present
|
||||||
|
state: present
|
||||||
|
################################}
|
||||||
|
{% if os9_dcb is defined and os9_dcb %}
|
||||||
|
{% set dcb_vars = os9_dcb %}
|
||||||
|
{% if dcb_vars.dcb_enable is defined %}
|
||||||
|
{% if dcb_vars.dcb_enable %}
|
||||||
|
dcb enable
|
||||||
|
{% else %}
|
||||||
|
no dcb enable
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if dcb_vars.dcb_map is defined and dcb_vars.dcb_map %}
|
||||||
|
{% for map in dcb_vars.dcb_map %}
|
||||||
|
{% if map.name is defined and map.name %}
|
||||||
|
{% if map.state is defined and map.state == "absent" %}
|
||||||
|
{% if map.intf is defined and map.intf %}
|
||||||
|
{% for intf in map.intf %}
|
||||||
|
{% if intf.state is defined and intf.state == "absent" %}
|
||||||
|
{% if intf.name is defined and intf.name %}
|
||||||
|
interface {{ intf.name }}
|
||||||
|
no dcb-map {{ map.name }}
|
||||||
|
exit
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
no dcb-map {{ map.name }}
|
||||||
|
{% else %}
|
||||||
|
dcb-map {{ map.name }}
|
||||||
|
{% set pgid_set = {'value': False} %}
|
||||||
|
{% if map.priority_group is defined and map.priority_group %}
|
||||||
|
{% for group in map.priority_group %}
|
||||||
|
{% if group.pgid is defined and group.pgid >= 0 %}
|
||||||
|
{% if group.state is defined and group.state == "absent" %}
|
||||||
|
{% if not pgid_set['value'] %}
|
||||||
|
{% if map.priority_pgid is defined %}
|
||||||
|
{% if pgid_set.update({'value': True}) %} {% endif %}
|
||||||
|
{% if map.priority_pgid %}
|
||||||
|
priority-pgid {{ map.priority_pgid }}
|
||||||
|
{% else %}
|
||||||
|
no priority-pgid
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
no priority-group {{ group.pgid }}
|
||||||
|
{% else %}
|
||||||
|
{% if group.bandwidth is defined and group.bandwidth %}
|
||||||
|
{% if group.pfc is defined %}
|
||||||
|
{% if group.pfc %}
|
||||||
|
priority-group {{ group.pgid }} bandwidth {{ group.bandwidth }} pfc on
|
||||||
|
{% else %}
|
||||||
|
priority-group {{ group.pgid }} bandwidth {{ group.bandwidth }} pfc off
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if not pgid_set['value'] %}
|
||||||
|
{% if map.priority_pgid is defined %}
|
||||||
|
{% if map.priority_pgid %}
|
||||||
|
priority-pgid {{ map.priority_pgid }}
|
||||||
|
{% else %}
|
||||||
|
no priority-pgid
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if map.intf is defined and map.intf %}
|
||||||
|
{% for intf in map.intf %}
|
||||||
|
{% if intf.name is defined and intf.name %}
|
||||||
|
interface {{ intf.name }}
|
||||||
|
{% if intf.state is defined and intf.state == "absent" %}
|
||||||
|
no dcb-map {{ map.name }}
|
||||||
|
{% else %}
|
||||||
|
dcb-map {{ map.name }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if dcb_vars.dcb_buffer is defined and dcb_vars.dcb_buffer %}
|
||||||
|
{% for buf in dcb_vars.dcb_buffer %}
|
||||||
|
{% if buf.name is defined and buf.name %}
|
||||||
|
{% if buf.state is defined and buf.state == "absent" %}
|
||||||
|
no dcb-buffer-threshold {{ buf.name }}
|
||||||
|
{% else %}
|
||||||
|
dcb-buffer-threshold {{ buf.name }}
|
||||||
|
{% if buf.description is defined and buf.description %}
|
||||||
|
description {{ buf.description }}
|
||||||
|
{% elif buf.description is defined and not buf.description %}
|
||||||
|
no description
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if buf.priority_params is defined and buf.priority_params %}
|
||||||
|
{% for params in buf.priority_params %}
|
||||||
|
{% if params.pgid is defined and params.pgid >= 0 %}
|
||||||
|
{% if params.state is defined and params.state == "absent" %}
|
||||||
|
{% if params.buffer_size is defined and params.buffer_size %}
|
||||||
|
{% if params.pause is defined and params.pause %}
|
||||||
|
{% if params.resume is defined and params.resume %}
|
||||||
|
no priority {{ params.pgid }} buffer-size {{ params.buffer_size }} pause-threshold {{ params.pause }} resume-offset {{ params.resume }}
|
||||||
|
{% else %}
|
||||||
|
no priority {{ params.pgid }} buffer-size {{ params.buffer_size }} pause-threshold {{ params.pause }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if params.resume is defined and params.resume %}
|
||||||
|
no priority {{ params.pgid }} buffer-size {{ params.buffer_size }} resume-offset {{ params.resume }}
|
||||||
|
{% else %}
|
||||||
|
no priority {{ params.pgid }} buffer-size {{ params.buffer_size }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if params.pause is defined and params.pause %}
|
||||||
|
{% if params.resume is defined and params.resume %}
|
||||||
|
no priority {{ params.pgid }} pause-threshold {{ params.pause }} resume-offset {{ params.resume }}
|
||||||
|
{% else %}
|
||||||
|
no priority {{ params.pgid }} pause-threshold {{ params.pause }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if params.resume is defined and params.resume %}
|
||||||
|
no priority {{ params.pgid }} resume-offset {{ params.resume }}
|
||||||
|
{% else %}
|
||||||
|
no priority {{ params.pgid }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if params.buffer_size is defined and params.buffer_size %}
|
||||||
|
{% if params.pause is defined and params.pause %}
|
||||||
|
{% if params.resume is defined and params.resume %}
|
||||||
|
priority {{ params.pgid }} buffer-size {{ params.buffer_size }} pause-threshold {{ params.pause }} resume-offset {{ params.resume }}
|
||||||
|
{% else %}
|
||||||
|
priority {{ params.pgid }} buffer-size {{ params.buffer_size }} pause-threshold {{ params.pause }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if params.resume is defined and params.resume %}
|
||||||
|
priority {{ params.pgid }} buffer-size {{ params.buffer_size }} resume-offset {{ params.resume }}
|
||||||
|
{% else %}
|
||||||
|
priority {{ params.pgid }} buffer-size {{ params.buffer_size }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if params.pause is defined and params.pause %}
|
||||||
|
{% if params.resume is defined and params.resume %}
|
||||||
|
priority {{ params.pgid }} pause-threshold {{ params.pause }} resume-offset {{ params.resume }}
|
||||||
|
{% else %}
|
||||||
|
priority {{ params.pgid }} pause-threshold {{ params.pause }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if params.resume is defined and params.resume %}
|
||||||
|
priority {{ params.pgid }} resume-offset {{ params.resume }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if buf.intf is defined and buf.intf %}
|
||||||
|
{% for intf in buf.intf %}
|
||||||
|
{% if intf.name is defined and intf.name %}
|
||||||
|
interface {{ intf.name }}
|
||||||
|
{% if intf.state is defined and intf.state == "absent" %}
|
||||||
|
no dcb-policy buffer-threshold {{ buf.name }}
|
||||||
|
{% else %}
|
||||||
|
dcb-policy buffer-threshold {{ buf.name }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
20
roles/os9_dcb/tests/inventory.yaml
Normal file
20
roles/os9_dcb/tests/inventory.yaml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
spine1 ansible_host=100.94.210.44
|
||||||
|
spine2 ansible_host=10.11.182.26
|
||||||
|
leaf1 ansible_host=10.11.182.27
|
||||||
|
leaf2 ansible_host=10.11.182.28
|
||||||
|
leaf3 ansible_host=10.11.182.29
|
||||||
|
leaf4 ansible_host=10.11.182.30
|
||||||
|
|
||||||
|
[spine]
|
||||||
|
spine1
|
||||||
|
spine2
|
||||||
|
|
||||||
|
[leaf]
|
||||||
|
leaf1
|
||||||
|
leaf2
|
||||||
|
leaf3
|
||||||
|
leaf4
|
||||||
|
|
||||||
|
[datacenter:children]
|
||||||
|
spine
|
||||||
|
leaf
|
38
roles/os9_dcb/tests/main.os9.yaml
Normal file
38
roles/os9_dcb/tests/main.os9.yaml
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
---
|
||||||
|
# vars file for dellemc.os9.os9_dcb,
|
||||||
|
# below gives a sample configuration
|
||||||
|
# Sample variables for OS9 device
|
||||||
|
os9_dcb:
|
||||||
|
dcb_enable: true
|
||||||
|
dcb_map:
|
||||||
|
- name: test
|
||||||
|
priority_pgid: 0 0 0 3 0 0 0 0
|
||||||
|
priority_group:
|
||||||
|
- pgid: 0
|
||||||
|
bandwidth: 50
|
||||||
|
pfc: false
|
||||||
|
state: present
|
||||||
|
- pgid: 3
|
||||||
|
bandwidth: 50
|
||||||
|
pfc: true
|
||||||
|
state: present
|
||||||
|
intf:
|
||||||
|
- name: fortyGigE 1/8
|
||||||
|
state: absent
|
||||||
|
- name: fortyGigE 1/9
|
||||||
|
state: present
|
||||||
|
dcb_buffer:
|
||||||
|
- name: buffer
|
||||||
|
description: testbuffer
|
||||||
|
priority_params:
|
||||||
|
- pgid: 0
|
||||||
|
buffer_size: 70
|
||||||
|
pause: 40
|
||||||
|
resume: 40
|
||||||
|
state: present
|
||||||
|
intf:
|
||||||
|
- name: fortyGigE 1/8
|
||||||
|
state: present
|
||||||
|
- name: fortyGigE 1/5
|
||||||
|
state: present
|
||||||
|
state: present
|
5
roles/os9_dcb/tests/test.yaml
Normal file
5
roles/os9_dcb/tests/test.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
- hosts: datacenter
|
||||||
|
connection: network_cli
|
||||||
|
roles:
|
||||||
|
- dellemc.os9.os9_dcb
|
2
roles/os9_dcb/vars/main.yml
Normal file
2
roles/os9_dcb/vars/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
# vars file for dellemc.os9.os9_dcb
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue