Skip to content

Commit

Permalink
HW2: add writeup
Browse files Browse the repository at this point in the history
  • Loading branch information
auerswal committed Mar 5, 2018
1 parent ec2dbcb commit dc31f8a
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 1 deletion.
116 changes: 115 additions & 1 deletion hw2-reports/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ format.

---

## Interlude 1: Beating Ansible Installation into Shape
### Interlude 1: Beating Ansible Installation into Shape

When I tried to use the `ios_command` module, it would fail with the error
message:
Expand All @@ -62,4 +62,118 @@ for the `ios_command` module, it missed the two Python packages `enum34` and

---

### Ansible Playbook

The solution approach provides a general structure for the Ansible playbook
[`topology.yml`](playbooks/topology.yml). I have used `tags` to allow
invoking parts of the playbook that belong together:

* `get` retrieves CDP neighbor information from network devices and writes the
raw CLI output to a file
* `parse` reads the raw CLI output from file and parses it into a data structure
* `graph` uses the data structure from the `parse` step to generate a DOT
language description of the graph (`connectivity.gv`) and a PNG image
visualizing it (`connectivity.png`)
* `debug_*` tags allow debugging of the respective steps

---

### Interlude 2: Lab Configuration

The lab as configured for [homework 1](../hw1-the_lab) lacks interesting
connectivity, thus I needed add some configuration. This is described in
the separate [Interlude 2](interlude2.md) document.

---

### Playbook Description

The following sections provide more information about the Ansible playbook
to create a visualization of the network connectivity.

#### One Play

The playbook comprises one play with several tasks. The network devices used
are specified at play level (the `OOB` group using the OOB interfaces, since
in-band connectivity is not yet established). Additionally, use of the `local`
connection is specified at play level, because all tasks are executed on
`localhost`:

* Files for intermediate steps and end result need to be created on the Ansible
host.
* Ansible network modules are executed on the Ansible host, the module then
connects to the network device.

A few variables to control where generated files are stored and how they are
named are defined at play level as well.

#### Tasks to Retrieve CDP Information

Four tasks (with the tag `get`) are used to retrieve CDP neighbor information
from the network devices. The first uses the `ios_command` module to issue
`show cdp neighbors detail` on each router. This information is written to
a text file in the fouth `get` task, after the second and thrid `get` tasks
have deleted old CDP information and (re-)created the directory to store it in.

#### Tasks to Parse CDP Information

Two tasks (with tag `parse`) are used to parse the CDP data to fill a data
structure that can be used in a Jinja2 template. The first reads the raw CDP
output using the Ansible `lookup` plugin `file`. The second uses the
`parse_cli_textfsm` filter with the
[TextFSM](https://github.com/google/textfsm)
[template](https://github.com/google/textfsm/wiki/TextFSM)
[`cdp_neighbors_detail.textfsm`](ansible/playbooks/cdp_neighbors_detail.textfsm)
to create a list with neighbor data.

#### Tasks to Graph the Topology

Four tasks (with tag `graph`) are used to generate an image that shows the
network topology. The first two tasks prepare the output directory, i.e.
they delete contents from previous playbook executions and (re-)create the
output directory. The third task uses the Ansible `template` module to
generate a DOT language description with the
[`connectivity.j2`](ansible/playbooks/templates/connectivity.j2)
Jinja2 template. The fourth task invokes the `dot` program using the Ansible
`command` module to generate a PNG image of the connectivity graph.

---

### Network Topology Visualization

The Ansible playbook [`topology.yml`](ansible/playbooks/topology.yml) generates
to result files:

1. The DOT language graph description [`connectivity.gv`](connectivity.gv)
2. The PNG image [`connectivity.png`](connectivity.png) of the topology

#### Topology Image

![Generated Topology Image](connectivity.png)

---

## References

* Ansible Filters
* [`parse_cli`](http://docs.ansible.com/ansible/latest/playbooks_filters.html#id20)
* [`parse_cli_textfsm`](http://docs.ansible.com/ansible/latest/playbooks_filters.html#id20)
* [Ansible Lookup Plugins](http://docs.ansible.com/ansible/latest/playbooks_lookups.html)
* Ansible Modules
* [`ios_command`](http://docs.ansible.com/ansible/latest/ios_command_module.html)
* [`ios_config`](https://docs.ansible.com/ansible/latest/ios_config_module.html)
* [Ansible Templating](https://docs.ansible.com/ansible/latest/playbooks_templating.html)
* [DOT language](https://graphviz.gitlab.io/_pages/doc/info/lang.html)
* [dot program](https://graphviz.gitlab.io/_pages/pdf/dotguide.pdf)
* [Graphviz](http://graphviz.org/)
* [Jinja2](http://jinja.pocoo.org/)
* [PNG](http://www.libpng.org/pub/png/)
* [Prescriptive Topology Manager](https://github.com/CumulusNetworks/ptm)
* ([PTM Documentation](https://docs.cumulusnetworks.com/display/DOCS/Prescriptive+Topology+Manager+-+PTM))
* [TextFSM](https://github.com/google/textfsm)
* [TextFSM template](https://github.com/google/textfsm/wiki/TextFSM)
* [YAML](http://yaml.org/)

---

[BNAS2018 GitHub repository](https://github.com/auerswal/bnas2018) | [My GitHub user page](https://github.com/auerswal) | [My home page](https://www.unix-ag.uni-kl.de/~auerswal/)
21 changes: 21 additions & 0 deletions hw2-reports/connectivity.gv
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
strict graph network_connectivity {
"P1.lab.local" [shape=record,label="P1.lab.local|<FastEthernet2/0> Fa2/0|<FastEthernet6/0> Fa6/0|<FastEthernet1/0> Fa1/0"];
"P2.lab.local" [shape=record,label="P2.lab.local|<FastEthernet2/0> Fa2/0|<FastEthernet1/0> Fa1/0"];
"PE1.lab.local" [shape=record,label="PE1.lab.local|<Ethernet6/1> Et6/1|<FastEthernet2/0> Fa2/0"];
"PE2.lab.local" [shape=record,label="PE2.lab.local|<Ethernet6/2> Et6/2|<FastEthernet2/0> Fa2/0"];
"RR1.lab.local" [shape=record,label="RR1.lab.local|<FastEthernet6/0> Fa6/0"];
"CE1.lab.local" [shape=record,label="CE1.lab.local|<Ethernet1/0> Et1/0"];
"CE2.lab.local" [shape=record,label="CE2.lab.local|<Ethernet1/0> Et1/0"];
"P1.lab.local":"FastEthernet2/0" -- "PE1.lab.local":"FastEthernet2/0";
"P1.lab.local":"FastEthernet6/0" -- "RR1.lab.local":"FastEthernet6/0";
"P1.lab.local":"FastEthernet1/0" -- "P2.lab.local":"FastEthernet1/0";
"P2.lab.local":"FastEthernet2/0" -- "PE2.lab.local":"FastEthernet2/0";
"P2.lab.local":"FastEthernet1/0" -- "P1.lab.local":"FastEthernet1/0";
"PE1.lab.local":"Ethernet6/1" -- "CE1.lab.local":"Ethernet1/0";
"PE1.lab.local":"FastEthernet2/0" -- "P1.lab.local":"FastEthernet2/0";
"PE2.lab.local":"Ethernet6/2" -- "CE2.lab.local":"Ethernet1/0";
"PE2.lab.local":"FastEthernet2/0" -- "P2.lab.local":"FastEthernet2/0";
"RR1.lab.local":"FastEthernet6/0" -- "P1.lab.local":"FastEthernet6/0";
"CE1.lab.local":"Ethernet1/0" -- "PE1.lab.local":"Ethernet6/1";
"CE2.lab.local":"Ethernet1/0" -- "PE2.lab.local":"Ethernet6/2";
}
Binary file added hw2-reports/connectivity.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions hw2-reports/interlude2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
## Interlude 2: Lab Configuration

The virtual lab as set up in [homework 1](../hw1-the_lab) enables just the
interfaces used for out-of-band management. These interfaces are connected
to a Linux bridge without CDP support. As a result every router sees all other
routers via CDP in the OOB interface. Since all physical router interfaces
are administratively down by default, the connectivity graph shows just
full mesh connectivity between the OOB interfaces and nothing more. That is
not the intended result for the topology visualization.

Thus I have written two playbooks to add some configuration to the virtual
network:

1. The playbook [`no_oob_mgmt_cdp.yml`](ansible/playbooks/no_oob_mgmt_cdp.yml)
disables CDP on the OOB interfaces, because I do not want to see this in
the topology graph. The OOB interfaces are intended for staging only, they
are not part of the production configuration. This is a simple playbook,
because just one command (`no cdp enable`) needs to be configured on the
same interface (`FastEthernet0/0`) of all routers. This is done with just
one task invoking the `ios_config` module in the single play of the
playbook.
2. The playbook [`configure_interfaces.yml`](ansible/playbooks/configure_interfaces.yml)
enables the transit interfaces between the routers, and additionally
configures IPv4 addresses on transit and loopback interfaces. (The IPv4
addresses are not used yet.) This playbook is a bit more complex than the
other. It reads a [YAML file](ansible/playbooks/vars/half_lab-interfaces.yml)
containing node descriptions, uses a
[Jinja2 template](ansible/playbooks/templates/ios-interfaces.j2) to generate
configuration snippets, and then uses the generated configuration as input
to the `ios_config` Ansible module.

---

[BNAS2018 Homework 2](README.md) | [BNAS2018 GitHub repository](https://github.com/auerswal/bnas2018) | [My GitHub user page](https://github.com/auerswal) | [My home page](https://www.unix-ag.uni-kl.de/~auerswal/)

0 comments on commit dc31f8a

Please sign in to comment.