This repository has been archived by the owner on Dec 3, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
saimkhan92
committed
Nov 6, 2018
1 parent
05a3879
commit c2e9adc
Showing
45 changed files
with
1,573 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,5 @@ napalm | |
netmiko | ||
jsnapy | ||
junos-eznc | ||
robotframework | ||
jinja2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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! | ||
|
Oops, something went wrong.