Skip to content

Commit fab43c5

Browse files
committed
Initial Commit
0 parents  commit fab43c5

File tree

105 files changed

+2668
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+2668
-0
lines changed

.gitignore

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
wheels/
23+
pip-wheel-metadata/
24+
share/python-wheels/
25+
*.egg-info/
26+
.installed.cfg
27+
*.egg
28+
MANIFEST
29+
30+
# PyInstaller
31+
# Usually these files are written by a python script from a template
32+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
33+
*.manifest
34+
*.spec
35+
36+
# Installer logs
37+
pip-log.txt
38+
pip-delete-this-directory.txt
39+
40+
# Unit test / coverage reports
41+
htmlcov/
42+
.tox/
43+
.nox/
44+
.coverage
45+
.coverage.*
46+
.cache
47+
nosetests.xml
48+
coverage.xml
49+
*.cover
50+
*.py,cover
51+
.hypothesis/
52+
.pytest_cache/
53+
54+
# Translations
55+
*.mo
56+
*.pot
57+
58+
# Django stuff:
59+
*.log
60+
local_settings.py
61+
db.sqlite3
62+
db.sqlite3-journal
63+
64+
# Flask stuff:
65+
instance/
66+
.webassets-cache
67+
68+
# Scrapy stuff:
69+
.scrapy
70+
71+
# Sphinx documentation
72+
docs/_build/
73+
74+
# PyBuilder
75+
target/
76+
77+
# Jupyter Notebook
78+
.ipynb_checkpoints
79+
80+
# IPython
81+
profile_default/
82+
ipython_config.py
83+
84+
# pyenv
85+
.python-version
86+
87+
# pipenv
88+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
90+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
91+
# install all needed dependencies.
92+
#Pipfile.lock
93+
94+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
95+
__pypackages__/
96+
97+
# Celery stuff
98+
celerybeat-schedule
99+
celerybeat.pid
100+
101+
# SageMath parsed files
102+
*.sage.py
103+
104+
# Environments
105+
.env
106+
.venv
107+
env/
108+
venv/
109+
ENV/
110+
env.bak/
111+
venv.bak/
112+
113+
# Spyder project settings
114+
.spyderproject
115+
.spyproject
116+
117+
# Rope project settings
118+
.ropeproject
119+
120+
# mkdocs documentation
121+
/site
122+
123+
# mypy
124+
.mypy_cache/
125+
.dmypy.json
126+
dmypy.json
127+
128+
# Pyre type checker
129+
.pyre/
130+
131+
# VSCode
132+
.vscode/
133+
134+
# Ignore Roles Files Directories
135+
roles/prepare_model/files
136+
roles/dtc/common/files/*
137+
roles/dtc/create/files
138+
roles/dtc/deploy/files
139+
roles/dtc/remove/files
140+
roles/validate/files/*

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Ansible Solution Collection: netascode_dc_vxlan
2+
Ansible collection for configuring a VXLAN Fabric using Direct to Controller (DTC) or Direct To Device (DTD) workflows.

docs/about.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Documentation for the netascode-dc-vxlan collection

galaxy.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
namespace: cisco
3+
name: nac_dc_vxlan
4+
version: 0.1.0
5+
readme: README.md
6+
authors:
7+
- Matt Tarkington <mtarking>
8+
- Mike Wiebe <mikewiebe>
9+
- Rafael Muller <rmuller>
10+
- Shangxin Du <shdu>
11+
description: Ansible solution collection for VXLAN
12+
license_file: LICENSE
13+
tags: [cisco, ndfc, dcnm, nxos, dnac, networking, vxlan]
14+
dependencies:
15+
"ansible.netcommon": ">=4.1.0"
16+
"cisco.ios": ">=4.3.0"
17+
"cisco.nxos": ">=4.0.1"
18+
"cisco.dcnm": ">=2.4.0"
19+
repository: https://github.com/netascode/ansible-dc-vxlan

images/.gitkeep

Whitespace-only changes.

plugins/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Collections Plugins Directory
2+
3+
This directory can be used to ship various plugins inside an Ansible collection. Each plugin is placed in a folder that
4+
is named after the type of plugin it is in. It can also include the `module_utils` and `modules` directory that
5+
would contain module utils and modules respectively.
6+
7+
Here is an example directory of the majority of plugins currently supported by Ansible:
8+
9+
```
10+
└── plugins
11+
├── action
12+
├── become
13+
├── cache
14+
├── callback
15+
├── cliconf
16+
├── connection
17+
├── filter
18+
├── httpapi
19+
├── inventory
20+
├── lookup
21+
├── module_utils
22+
├── modules
23+
├── netconf
24+
├── shell
25+
├── strategy
26+
├── terminal
27+
├── test
28+
└── vars
29+
```
30+
31+
A full list of plugin types can be found at [Working With Plugins](https://docs.ansible.com/ansible-core/2.13/plugins/plugins.html).
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
from __future__ import absolute_import, division, print_function
2+
3+
4+
__metaclass__ = type
5+
6+
from ansible import constants as C
7+
from ansible.utils.display import Display
8+
from ansible.plugins.action import ActionBase
9+
10+
from ..helper_functions import do_something
11+
12+
import iac_validate.validator
13+
from iac_validate.yaml import load_yaml_files
14+
import os
15+
16+
display = Display()
17+
18+
class ActionModule(ActionBase):
19+
20+
def run(self, tmp=None, task_vars=None):
21+
results = super(ActionModule, self).run(tmp, task_vars)
22+
results['failed'] = False
23+
results['msg'] = None
24+
results['data'] = {}
25+
26+
schema = self._task.args.get('schema')
27+
rules = self._task.args.get('rules')
28+
mdata = self._task.args.get('mdata')
29+
30+
# Generate a warning if the Schema and Rules are not provided
31+
if schema and not os.path.exists(schema):
32+
display.warning("The provided schema ({0}) does not appear to exist! ".format(schema))
33+
# The rules directory is considered empty if it only contains the .gitkeep file
34+
if len(os.listdir(rules)) == 1 and '.gitkeep' in os.listdir(rules):
35+
display.warning("The rules directory ({0}) is empty! ".format(rules))
36+
37+
# Verify That Data Sources Exists
38+
if mdata and not os.path.exists(mdata):
39+
results['failed'] = True
40+
results['msg'] = "The data directory ({0}) for this fabric does not appear to exist!".format(mdata)
41+
return results
42+
if len(os.listdir(mdata)) == 0:
43+
results['failed'] = True
44+
results['msg'] = "The data directory ({0}) for this fabric is empty!".format(mdata)
45+
return results
46+
47+
if schema is None:
48+
schema = ""
49+
if rules is None:
50+
rules = ""
51+
52+
validator = iac_validate.validator.Validator(schema, rules)
53+
if schema:
54+
validator.validate_syntax([mdata])
55+
if rules:
56+
validator.validate_semantics([mdata])
57+
58+
msg = ""
59+
for error in validator.errors:
60+
msg += error + "\n"
61+
62+
if msg:
63+
results['failed'] = True
64+
results['msg'] = msg
65+
66+
# Return Schema Validated Model Data
67+
results['data'] = load_yaml_files([mdata])
68+
69+
return results
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class PreparePlugin:
2+
def __init__(self, **kwargs):
3+
self.kwargs = kwargs
4+
self.keys = []
5+
6+
def prepare(self):
7+
model_data = self.kwargs['results']['model_extended']
8+
self.kwargs['results']['model_extended'] = model_data
9+
return self.kwargs['results']
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
class PreparePlugin:
2+
def __init__(self, **kwargs):
3+
self.kwargs = kwargs
4+
self.keys = ['fabric', 'topology', 'switches']
5+
6+
def prepare(self):
7+
model_data = self.kwargs['results']['model_extended']
8+
9+
if model_data.get(self.keys[0]).get(self.keys[1]).get(self.keys[2]) is not None:
10+
model_data['fabric']['topology']['spine'] = {}
11+
model_data['fabric']['topology']['leaf'] = {}
12+
sm_switches = model_data['fabric']['topology']['switches']
13+
for switch in sm_switches:
14+
# Build list of switch IP's based on role keyed by switch name
15+
name = switch.get('name')
16+
role = switch.get('role')
17+
model_data['fabric']['topology'][role][name] = {}
18+
v4_key = 'management_ipv4_address'
19+
v6_key = 'management_ipv6_address'
20+
v4ip = switch.get('management').get(v4_key)
21+
v6ip = switch.get('management').get(v6_key)
22+
model_data['fabric']['topology'][role][name][v4_key] = v4ip
23+
model_data['fabric']['topology'][role][name][v6_key] = v6ip
24+
25+
self.kwargs['results']['model_extended'] = model_data
26+
return self.kwargs['results']
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
class PreparePlugin:
2+
def __init__(self, **kwargs):
3+
self.kwargs = kwargs
4+
self.keys = ['fabric', 'overlay_services', 'vrfs', 'networks']
5+
6+
def prepare(self):
7+
model_data = self.kwargs['results']['model_extended']
8+
9+
# Handle VRFs/Networks Under Overlay Services. Need to create an empty list
10+
# if vrfs/networks or vrf/networks key is not present in the service model data
11+
if model_data.get('fabric').get('overlay_services') is None:
12+
model_data['fabric']['overlay_services'] = {'vrfs': []}
13+
model_data['fabric']['overlay_services'] = {'networks': []}
14+
if model_data.get('fabric').get('overlay_services').get('vrfs') is None:
15+
model_data['fabric']['overlay_services']['vrfs'] = []
16+
if model_data.get('fabric').get('overlay_services').get('networks') is None:
17+
model_data['fabric']['overlay_services']['networks'] = []
18+
19+
# Rebuild sm_data['fabric']['overlay_services']['vrf_attach_groups'] into
20+
# a structure that is easier to use.
21+
model_data['fabric']['overlay_services']['vrf_attach_groups_dict'] = {}
22+
for grp in model_data['fabric']['overlay_services']['vrf_attach_groups']:
23+
model_data['fabric']['overlay_services']['vrf_attach_groups_dict'][grp['name']] = []
24+
for switch in grp['switches']:
25+
model_data['fabric']['overlay_services']['vrf_attach_groups_dict'][grp['name']].append(switch)
26+
27+
# Rebuild sm_data['fabric']['overlay_services']['network_attach_groups'] into
28+
# a structure that is easier to use.
29+
model_data['fabric']['overlay_services']['network_attach_groups_dict'] = {}
30+
for grp in model_data['fabric']['overlay_services']['network_attach_groups']:
31+
model_data['fabric']['overlay_services']['network_attach_groups_dict'][grp['name']] = []
32+
for switch in grp['switches']:
33+
model_data['fabric']['overlay_services']['network_attach_groups_dict'][grp['name']].append(switch)
34+
35+
self.kwargs['results']['model_extended'] = model_data
36+
return self.kwargs['results']

0 commit comments

Comments
 (0)