Skip to content
This repository has been archived by the owner on Dec 3, 2021. It is now read-only.

Commit

Permalink
added robot tutorial chapter 1-3
Browse files Browse the repository at this point in the history
  • Loading branch information
saimkhan92 committed Nov 6, 2018
1 parent 05a3879 commit c2e9adc
Show file tree
Hide file tree
Showing 45 changed files with 1,573 additions and 24 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*.retry
hosts
venv/
*.pyc

# This is where I placed my updated gcp provider
terraform.d/
Expand Down Expand Up @@ -39,3 +40,5 @@ _old_contrail/
*ansiblekey.json

platform/antidote-web/target/

__pycache__
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,27 @@

### Curriculum

- Adding Lesson-16 Jinja2 Templates [#121](https://github.com/nre-learning/antidote/pull/121)

### Other

## 0.1.2 - October 29, 2018

### Curriculum

### Other


## 0.1.1 - October 28, 2018

### Curriculum

- Fixed typos in YAML lesson (change) - [#109](https://github.com/nre-learning/antidote/pull/109) (contributed by pklimai)

### Other

- Significant restructuring of docs, and large improvements to contribution pages [#108](https://github.com/nre-learning/antidote/pull/108)
- Added "tier" field to all syringe files [#116](https://github.com/nre-learning/antidote/pull/116)

## v0.1.0

Expand Down
24 changes: 24 additions & 0 deletions docs/contributing/curriculum.rst
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,33 @@ Here are a few things that reviewers should be on the lookout for when reviewing
curriculum, either for new or existing lessons. If you're contributing to the curriculum, you should be aware
of these guidelines, to make the review process much smoother.

- Can a user get through a lesson stage quickly? Are we letting them get to a quick win as soon as practical while still teaching quality content?
- Does the new or changed lesson adhere to the spirit of Antidote lessons laid out in this document?
- For new lessons, does the lesson guide (or jupyter notebook if applicable) look nice? Does the author attribute themselves?
- Is the lesson guide(s) easy to follow?
- Are any documentation updates also needed?
- Is the CHANGELOG updated properly?
- Can we show this in NRE labs? Usage rights?
- Is the business benefit clear from this lesson? How easy is it for people to link this content with their day-to-day?

Appendix - Lesson Contribution FAQ
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

**NAPALM Can't Find My Configs.**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is likely due to the way you've deployed syringe.

In the selfmedicate repo, there are a number of kubernetes manifests useful for running antidote locally.
However, there are some defaults here you'll likely want to change. In particular, if you're making lesson
changes in a branch or fork (which is ideal if you want to open a PR) you will want to make sure you update
the syringe deployment in two places:

- The init-container definition, where the ``antidote`` repo
is cloned into the syringe pod
- Syringe's ``SYRINGE_LESSON_REPO_REMOTE`` and ``SYRINGE_LESSON_REPO_BRANCH``
environment variables.

Be sure to re-deploy syringe using ``kubectl apply -f syringe.yaml`` once you've made the appropriate changes.
If you've already made these changes and it still doesn't work, make sure syringe is using the latest copy
of your repo by deleting the syringe pod. The Syringe deployment will re-deploy a new pod with a freshly-cloned
version of your lesson repo.
5 changes: 2 additions & 3 deletions docs/contributing/ptr.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ However, there's a version of NRE Labs that is deployed every time a change to `
on one of Antidote's repositories, called the "public test realm". It's located at:
`https://ptr.labs.networkreliability.engineering/ <https://ptr.labs.networkreliability.engineering/>`_.


The NRE Labs PTR will be quite similar to the "production" copy, but there are a few
important differences to discuss:

* Everything is deployed via ``master``, and is inherently unstable. We will try to keep things working,
but it **is** a test realm. There be dragons here.
* Everything is deployed via ``master`` or the current release branch, and is inherently unstable.
We will try to keep things working, but it **is** a test realm. There be dragons here.
* All lessons in the ``antidote`` repository are shown, despite the `disabled` property in the
syringe file.
* A black bar with the latest commit ID for all three projects (``antidote``, ``antidote-web``,
Expand Down
13 changes: 13 additions & 0 deletions docs/ops.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@



# kubectl create sa stanley
# kubectl create clusterrolebinding owner-cluster-admin-binding \
# --clusterrole cluster-admin \
# --user stanley
# secret=$(kubectl get sa stanley -o json | jq -r '.secrets[0].name')
# kubectl get secret $secret -o json | jq -r '.data["token"]' | base64 -D


# kubectl get secret $secret -o json | jq -r '.data["ca.crt"]' | base64 -D > ca.crt

2 changes: 2 additions & 0 deletions images/utility/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ napalm
netmiko
jsnapy
junos-eznc
robotframework
jinja2
5 changes: 1 addition & 4 deletions lessons/lesson-12/syringe.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@ lessonName: Network Unit Testing with JSNAPY
lessonID: 12
category: verification
lessondiagram: https://raw.githubusercontent.com/nre-learning/antidote/master/lessons/lesson-12/lessondiagram.png


topologyType: custom

# TODO(mierdin): What about IP addressing for utilities?
tier: prod

utilities:
- name: linux1
Expand Down
1 change: 1 addition & 0 deletions lessons/lesson-13/syringe.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ lessonName: Multi-Vendor Network Automation with NAPALM
lessonID: 13
category: configuration
topologyType: custom
tier: prod


utilities:
Expand Down
2 changes: 1 addition & 1 deletion lessons/lesson-14/syringe.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
lessonName: Introduction to YAML
lessonID: 14
category: introductory

topologyType: none
tier: prod

utilities:
- name: linux1
Expand Down
1 change: 1 addition & 0 deletions lessons/lesson-15/syringe.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ lessonName: Event-Driven Network Automation with StackStorm
lessonID: 15
category: configuration
disabled: true
tier: ptr

topologyType: custom

Expand Down
79 changes: 76 additions & 3 deletions lessons/lesson-16/stage1/guide.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,77 @@
# Using Jinja for Configuration Templates
## Part 1 - Intro
# Using Jinja for Configuration Templates
**Contributed by: [@ShrutiVPawaskar](https://github.com/ShrutiVPawaskar) and [@shahbhoomi](https://github.com/shahbhoomi)**
## Part 1 - Introduction to Jinja2

Jinja lesson.
I am sure at some point you might have heard the word “Jinja2”. So, what is Jinja2?? Why do you need to invest your time in learning Jinja2 and go through these lessons? We will answer all your questions in this lesson!

### What are Templates?
* A template is a text document where some or all of the content is dynamically generated.
* Data is automatically loaded to the templates with the help of template variables. You can also say that the templates are reusable text files.

### What is Jinja2? Why do we use it?
* Jinja2 is a modern and designer-friendly templating language for Python. It is prevalent in the DevOps/NetOps community.
* It has gained a lot of popularity as it has a lot of information published and is supported by tools like Ansible, StackStorm, and Salt.
* Template Inheritance: It allows you to build a base “skeleton” template that contains all the common elements of your site and defines blocks that child templates can override.

So, let’s begin with our first example and get you started with your Jinja2 Adventure!!

First, we need to install Jinja2 using `pip install jinja2`(it is preinstalled for these lessons). Next, open an interactive python shell by running the snippet below and import the template module from Jinja2.
```
python
from jinja2 import Template
```
<button type="button" class="btn btn-primary btn-sm" onclick="runSnippetInTab('linux1', 0)">Run this snippet</button>

Run the below snippet to see the sample output we plan on achieving using our Jinja2 Template.
```
print('ge-0/0/0 has IP address 192.168.1.1')
```
<button type="button" class="btn btn-primary btn-sm" onclick="runSnippetInTab('linux1', 1)">Run this snippet</button>

### Template Syntax:

```
template_name = Template('some_text {{template_variable1}} some_text')
```
where `{{template_variable1}}` is the template variable and template_name is the name of the template. `Template()` function converts your text into a reusable Jinja2 template.

Let us look at Example 1 to learn how to use these templates. Here `ipaddr_template` is the Jinja2 Template and `{{interface}}` and `{{ip_address}}` are the template variables.

### Example: 1
```
ipaddr_template = Template('{{interface}} has IP address {{ip_address}}')
```
<button type="button" class="btn btn-primary btn-sm" onclick="runSnippetInTab('linux1', 3)">Run this snippet</button>

Now that our template is ready, we want to load the data in it. This can be done with the help of the `template.render()` function. `template.render()` will take the data you supply to the template variables and load it to the template. Check that out by running the below snippet.

```
interface_1 = ipaddr_template.render(interface='ge-0/0/0',
ip_address='192.168.1.1')
print(str(interface_1))
```

<button type="button" class="btn btn-primary btn-sm" onclick="runSnippetInTab('linux1', 4)">Run this snippet</button>

let’s look at Example 2 and supply the different variable values to our Jinaj2 template aka "Resuable Text File".

### Example: 2

```
render_2 = ipaddr_template.render(interface='ge-0/0/1',
ip_address='10.10.1.1')
print(str(render_2))
```
<button type="button" class="btn btn-primary btn-sm" onclick="runSnippetInTab('linux1', 5)">Run this snippet</button>

That’s all for stage-1, in coming lessons we will look into how to use a list or dictionary of variables to populate the template. But before that we expect you to have the following take away from stage-1.

### Take-away from Stage 1:
* Jinja2 is a templating tool
* Jinja2 templates are the text files that sets the format of your output
* `{{}}` shows the template variables and can be loaded to the template using the `render()` function.
* As seen from example 1 and 2, Jinja2 templates can be “reused” with a different set of variables.

That’s all for now; next, we will look into how to use a list or dictionary of variables to populate the template.

Hope you enjoyed it!! See you in stage-2!
98 changes: 98 additions & 0 deletions lessons/lesson-16/stage2/guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Using Jinja for Configuration Templates
## Part 2 – For Loops

Now that you know what is a template and how it works, let’s dive deep into using `for` loops for variable assignment.
For loops are very useful if you have your data in the form of a list/dictionary or the combination of both. In this part we will take an example which has data stored as a list of dictionaries.

First, we want to start the Python interpreter and import `Environment` module from Jinja2 library.

```
python
from jinja2 import Environment
```
<button type="button" class="btn btn-primary btn-sm" onclick="runSnippetInTab('linux1', 0)">Run this snippet</button>

### Python Syntax:

In case you haven’t worked with python lists and dictionaries, below is the syntax for them:
List: `[a, b, c]`
Where `a`, `b`, `c` are the elements of the list

Dictionary: `{x: a, y: b, z: c}`
where `x`, `y`, `z` are the keys and `a`, `b`, `c` are the values of the keys

In our example `interface` and `ip_address` are the keys and `ge-0/0/0` and `192.168.1.1` are the values of those keys. All these key value pairs are the list elements of the list `interfaces`.

Run the below snippet to define `interfaces` which will later be used to populate our template.

### Example: 1
```
interfaces = [{'interface': 'ge-0/0/0', 'ip_address': '192.168.1.1'},
{'interface': 'ge-0/0/1', 'ip_address': '10.10.1.1'},
{'interface': 'fxp0', 'ip_address': '172.16.1.1'}]
```
<button type="button" class="btn btn-primary btn-sm" onclick="runSnippetInTab('linux1', 1)">Run this snippet</button>

Now once we have our data, we will use `for` loop to iterate through our list of dictionary and populate the template. Below is the syntax of `for` loop:

```
{% for condition %}
...
{% endfor %}
```

Lets analyze the `for` loop in the snippet below,
`{% for item in interfaces %}` iterates over each dictionary in the list `interfaces`.
The `trim_blocks` is a optional Enviroment parameters, and is used to trim an extra new line characters between consecutive iterations.
Similarly, `lstrip_block` is a optional Enviroment parameter for striping an extra space/tab before a block.
We are using `env.from_string` which accepts a template in form of a string.
`{{ item.interface }} has IP address {{ item.ip_address }}` replaces the template variable `interface` with the value for the key `interface` and replace `ip_address` with the item’s value for the key `ip_address`.

```
env = Environment(trim_blocks=True, lstrip_blocks=True)
ipaddr_template = env.from_string('''
{% for item in interfaces %}
{{ item.interface }} has IP address {{ item.ip_address }}
{% endfor %}''')
render_1 = ipaddr_template.render(interfaces=interfaces)
print(str(render_1))
```
<button type="button" class="btn btn-primary btn-sm" onclick="runSnippetInTab('linux1', 3)">Run this snippet</button>


Now let us define one more list of dictionaries for vlans.

### Example: 2
```
vlans = [{'vlan': 'VLAN10', 'vlan_id': 10},
{'vlan': 'VLAN20', 'vlan_id': 20},
{'vlan': 'VLAN30', 'vlan_id': 20}]
```
<button type="button" class="btn btn-primary btn-sm" onclick="runSnippetInTab('linux1', 4)">Run this snippet</button>

Now we will learn how to use the `for` loop to format the template like a Junos CLI configuration.

```
vlan_config = env.from_string('''
vlans {
{% for item in vlans %}
{{ item.vlan }} {
vlan-id {{ item.vlan_id }};
l3-interface irb.{{item.vlan_id}};
}
{% endfor %}
}''')
```
<button type="button" class="btn btn-primary btn-sm" onclick="runSnippetInTab('linux1', 5)">Run this snippet</button>

After creating the template, lets supply the vlans data and see how it looks!
```
vlan_config = str(vlan_config.render(vlans=vlans))
print(vlan_config)
```
<button type="button" class="btn btn-primary btn-sm" onclick="runSnippetInTab('linux1', 6)">Run this snippet</button>

So far, we have been loading all the available data to the template.
What if you don’t want to load everything and are only interested in loading a part of the data? That’s when template filters come in, check it out in next part!

Loading

0 comments on commit c2e9adc

Please sign in to comment.