Skip to content

Commit

Permalink
Merge pull request #41 from aristanetworks/feature-cvp-deployment
Browse files Browse the repository at this point in the history
Feature cvp deployment
  • Loading branch information
carlbuchmann authored Feb 11, 2020
2 parents b8830e2 + 385c8dc commit 3b8c185
Show file tree
Hide file tree
Showing 35 changed files with 887 additions and 61 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,6 @@ venv.bak/
.mypy_cache/

.vscode/*

# Installation path for CVP example
examples/evpn-l3ls-cvp-deployment/collections
31 changes: 28 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ The documentation how to leverage ansible-avd collection is located here: **[ari

**Ansible + Additional Python Libraries Installation:**

```bash
```shell
pip3 install -r requirements.txt
```

Expand Down Expand Up @@ -90,7 +90,31 @@ ansible-galaxy collection install arista.avd

## Example Playbooks

An example playbook to deploy VXLAN/EVPN Fabric via eAPI:
**An example playbook to deploy VXLAN/EVPN Fabric via CloudVision:**

![Figure 1: Example Playbook CloudVision Deployment](media/figure-1-example-playbook-evpn-deploy-cvp.gif)

```yml
- hosts: DC1_FABRIC

tasks:

- name: generate intended variables
import_role:
name: arista.avd.eos_l3ls_evpn

- name: generate device intended config and documentation
import_role:
name: arista.avd.eos_cli_config_gen

- name: deploy configuration via CVP
import_role:
name: arista.avd.eos_config_deploy_cvp
```
**An example playbook to deploy VXLAN/EVPN Fabric via eAPI:**
![Figure 2: Example Playbook CloudVision Deployment](media/figure-2-example-playbook-evpn-deploy-eapi.gif)
```yml
- hosts: DC1_FABRIC
Expand All @@ -112,7 +136,8 @@ An example playbook to deploy VXLAN/EVPN Fabric via eAPI:
## Examples
Full examples with variables and outputs, are located here:
**Full examples with variables and outputs, are located here:**
[Arista NetDevOps Examples](https://github.com/aristanetworks/netdevops-examples)
## Additional Resources
Expand Down
34 changes: 30 additions & 4 deletions ansible_collections/arista/avd/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ This repository provides roles for Ansible's collection __arista.avd__ with the

- [__arista.avd.eos_l3ls_evpn__](roles/eos_l3ls_evpn/README.md) - Opinionated Data model for deployment of L3 Leaf and Spine Fabric with VXLAN data-plane with an EVPN Control plane.
- [__arista.avd.eos_cli_config_gen__](roles/eos_cli_config_gen/README.md) - Generate Arista EOS cli syntax and device documentation.
- [__arista.avd.eos_config_deploy_cvp__](roles/eos_config_deploy_cvp/README.md) - deploys intended configuration via CloudVision.
- [__arista.avd.eos_config_deploy_eapi__](roles/eos_config_deploy_eapi/README.md) - deploys intended configuration via eAPI.

## Custom Plugins
Expand Down Expand Up @@ -53,7 +54,7 @@ This repository provides custom plugins for Ansible's collection __arista.avd__

**Ansible + Additional Python Libraries Installation:**

```bash
```shell
pip3 install -r requirements.txt
```

Expand Down Expand Up @@ -90,7 +91,31 @@ ansible-galaxy collection install arista.avd

## Example Playbooks

An example playbook to deploy VXLAN/EVPN Fabric via eAPI:
**An example playbook to deploy VXLAN/EVPN Fabric via CloudVision:**

![Figure 1: Example Playbook CloudVision Deployment](media/figure-1-example-playbook-evpn-deploy-cvp.gif)

```yml
- hosts: DC1_FABRIC

tasks:

- name: generate intended variables
import_role:
name: arista.avd.eos_l3ls_evpn

- name: generate device intended config and documentation
import_role:
name: arista.avd.eos_cli_config_gen

- name: deploy configuration via CVP
import_role:
name: arista.avd.eos_config_deploy_cvp
```
**An example playbook to deploy VXLAN/EVPN Fabric via eAPI:**
![Figure 2: Example Playbook CloudVision Deployment](media/figure-2-example-playbook-evpn-deploy-eapi.gif)
```yml
- hosts: DC1_FABRIC
Expand All @@ -110,9 +135,10 @@ An example playbook to deploy VXLAN/EVPN Fabric via eAPI:
name: arista.avd.eos_config_deploy_eapi
```
Full examples with variables and outputs, are located here:
**Full examples with variables and outputs, are located here:**
[Arista NetDevOps Examples](https://github.com/aristanetworks/netdevops-examples)
## License
Project is published under [Apache 2.0 License](../../../LICENSE)
Project is published under [Apache 2.0 License](LICENSE)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
79 changes: 79 additions & 0 deletions ansible_collections/arista/avd/plugins/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,82 @@ To use this filter:
{{ natural_sorted_item }}
{% endfor %}
```

## Modules

### **Inventory to CloudVision Containers**

The `inventory_to_container` module provides following capabilities:
- Transform inventory groups into CloudVision containers topology.
- Create list of configlets definition.

It saves everything in a `YAML` file using **`destination`** keyword.

It is a module to build structure of data to configure on a CloudVision server. Output is ready to be passed to [`arista.cvp`](https://github.com/aristanetworks/ansible-cvp/) to configure **CloudVision**.

**Example:**

To use this module:

```yaml
tasks:
- name: generate intented variables
tags: [always]
inventory_to_container:
inventory: '{{ inventory_file }}'
container_root: '{{ container_root }}'
configlet_dir: 'intended/configs'
configlet_prefix: '{{ configlets_prefix }}'
destination: '{{playbook_dir}}/intended/structured_configs/{{inventory_hostname}}.yml'
```
Inventory example applied to this example:
```yaml
all:
children:
# DC1_Fabric - EVPN Fabric running in home lab
DC1:
children:
DC1_FABRIC:
children:
DC1_SPINES:
hosts:
DC1-SPINE1:
DC1-SPINE2:
DC1_L3LEAFS:
children:
DC1_LEAF1:
hosts:
DC1-LEAF1A:
DC1-LEAF1B:
DC1_LEAF2:
hosts:
DC1-LEAF2A:
DC1-LEAF2B:
```
Generated output ready to be used by [`arista.cvp`](https://github.com/aristanetworks/ansible-cvp/) collection:

```yaml
---
CVP_DEVICES:
DC1-SPINE1:
name: DC1-SPINE1
parentContainerName: DC1_SPINES
configlets:
- DC1-AVD_DC1-SPINE1
imageBundle: []
CVP_CONTAINERS:
DC1_LEAF1:
parent_container: DC1_L3LEAFS
DC1_FABRIC:
parent_container: Tenant
DC1_L3LEAFS:
parent_container: DC1_FABRIC
DC1_LEAF2:
parent_container: DC1_L3LEAFS
DC1_SPINES:
parent_container: DC1_FABRIC
```
25 changes: 13 additions & 12 deletions ansible_collections/arista/avd/plugins/filter/list_compress.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
#
# list_compress filter
#
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

from jinja2 import TemplateError
from itertools import count, groupby
from ansible.errors import AnsibleFilterError

import re

class FilterModule(object):

def list_compress(self,list_to_compress):
if not isinstance(list_to_compress, list):
raise AnsibleFilterError('value must be of type list, got %s' % type(list_to_compress))

G=(list(x) for _,x in groupby(sorted(list_to_compress), lambda x,c=count(): next(c)-x))
return (",".join("-".join(map(str,(g[0],g[-1])[:len(g)])) for g in G))
class FilterModule(object):

def list_compress(self, list_to_compress):
if not isinstance(list_to_compress, list):
raise AnsibleFilterError('value must be of type list, got %s' % type(list_to_compress))
G = (list(x) for y, x in groupby(sorted(list_to_compress), lambda x, c=count(): next(c) - x))
return (",".join("-".join(map(str, (g[0], g[-1])[:len(g)])) for g in G))

def filters(self):
return {
'list_compress' : self.list_compress,
}
def filters(self):
return {
'list_compress': self.list_compress,
}
27 changes: 18 additions & 9 deletions ansible_collections/arista/avd/plugins/filter/natural_sort.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
#
# natural_sort filter
#
from jinja2 import TemplateError
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

from jinja2 import TemplateError
import re


def convert(text):
return int(text) if text.isdigit() else text.lower()


def alphanum_key(key):
return [convert(c) for c in re.split('([0-9]+)', str(key))]


class FilterModule(object):

def natural_sort(self,iterable):
convert = lambda text: int(text) if text.isdigit() else text.lower()
alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', str(key)) ]
return sorted(iterable, key = alphanum_key)
def natural_sort(self, iterable):
return sorted(iterable, key=alphanum_key)

def filters(self):
return {
'natural_sort' : self.natural_sort,
}
def filters(self):
return {
'natural_sort': self.natural_sort,
}
Loading

0 comments on commit 3b8c185

Please sign in to comment.