├── 10_get_config.py
├── 11_file_system.py
├── 12_utils_scp.py
├── 13_utils_sw_install.py
├── 14_utils_startshell.py
├── 1_gather_facts.py
├── 2_rpc_call.py
├── 3_cli_call.py
├── 4_load_text_config.py
├── 5_load_xml_config.py
├── 6_load_temp_conf.py
├── 7_rollback_config.py
├── 8_table_view.py
├── 9_user_defined_table.py
├── PyEZ_2_0_0.ipynb
├── PyEZ_demo_sept.ipynb
├── README.md
├── console.ipynb
├── fpc-info.py
├── generate_conf_from_template.py
├── images
└── serial_conn.jpg
├── plot_tcp.py
├── protocol_data.yml
├── protocol_temp.j2
├── table_view_from_existing_xml_file.py
└── templates
├── 1_temp.j2
├── create_vlans.conf
├── data_vars.yaml
├── filter.j2
├── generate_conf_from_template.py
├── main.j2
├── main_vlans.conf
├── remove_vlans.conf
├── sshkeys
├── lakhan
├── lakhan.pub
├── ram
└── ram.pub
├── template.j2
├── users.j2
├── vlans.csv
├── yaml_jinja_demo.ipynb
└── yaml_jinja_demo.md
/10_get_config.py:
--------------------------------------------------------------------------------
1 | from jnpr.junos import Device
2 | from lxml import etree
3 |
4 | dev = Device(host='xxxx', user='demo', password='demo123', gather_facts=False)
5 | dev.open()
6 |
7 | cnf = dev.rpc.get_config()
8 | #cnf = dev.rpc.get_config(filter_xml=etree.XML(''))
9 | print etree.tostring(cnf)
10 |
--------------------------------------------------------------------------------
/11_file_system.py:
--------------------------------------------------------------------------------
1 | from jnpr.junos.utils.fs import FS
2 | from jnpr.junos import Device
3 |
4 | dev = Device(host='xxxx', user='demo', password='demo123')
5 | dev.open()
6 |
7 | fs = FS(dev)
8 | pprint(fs.ls('/var/tmp'))
9 |
10 | dev.close()
11 |
--------------------------------------------------------------------------------
/12_utils_scp.py:
--------------------------------------------------------------------------------
1 | from jnpr.junos import Device
2 | from jnpr.junos.utils.scp import SCP
3 |
4 | dev = Device(host='xxxx', user='demo', password='demo123')
5 | dev.open()
6 |
7 | with SCP(dev, progress=True) as scp:
8 | scp.get('/var/tmp/nitin.log','info.txt')
9 | dev.close()
10 |
--------------------------------------------------------------------------------
/13_utils_sw_install.py:
--------------------------------------------------------------------------------
1 | from jnpr.junos import Device
2 | from jnpr.junos.utils.sw import SW
3 |
4 | dev = Device(host='xxxx', user='demo', password='demo123', gather_facts=False)
5 | dev.open()
6 |
7 | def update_progress(dev, report):
8 | print dev.hostname, '> ', report
9 |
10 | sw = SW(dev)
11 | ok = sw.install(package=r'/Users/nitinkr/Downloads/jinstall-1x.1xxxx.tgz', progress=update_progress)
12 | # progress takes boolean values too from 1.2.3 version onwards
13 | #ok = sw.install(package=r'/Users/nitinkr/Downloads/jinstall-1x.1xxxx.tgz', progress=True)
14 | if ok:
15 | print 'rebooting'
16 | sw.reboot()
17 |
--------------------------------------------------------------------------------
/14_utils_startshell.py:
--------------------------------------------------------------------------------
1 | from jnpr.junos.utils.start_shell import StartShell
2 | from jnpr.junos import Device
3 | from jnpr.junos.utils.scp import SCP
4 |
5 | dev = Device(host='xxxx', user='demo', password='demo123')
6 | dev.open()
7 |
8 | ss = StartShell(dev)
9 | ss.open()
10 | ss.run('cli -c "request support information | save /var/tmp/information.txt"')
11 | with SCP(dev) as scp:
12 | scp.get('/var/tmp/information.txt','info.txt')
13 |
14 | ss.close()
15 |
--------------------------------------------------------------------------------
/1_gather_facts.py:
--------------------------------------------------------------------------------
1 | from jnpr.junos import Device
2 | from pprint import pprint
3 |
4 | dev = Device(host='xxxx', user='demo', password='demo123')
5 | dev.open()
6 |
7 | pprint (dev.facts)
8 |
--------------------------------------------------------------------------------
/2_rpc_call.py:
--------------------------------------------------------------------------------
1 | from jnpr.junos import Device
2 | from lxml import etree
3 |
4 | dev = Device(host='xxxx', user='demo', password='demo123', gather_facts=False)
5 | dev.open()
6 |
7 | op = dev.rpc.get_interface_information()
8 | #op = dev.rpc.get_interface_information({'format': 'text'})
9 | #op = dev.rpc.get_interface_information(interface_name='lo0', terse=True)
10 | print (etree.tostring(op))
11 |
12 | #for i in op.xpath('.//link-level-type'):
13 | # print i.text
14 | dev.close()
15 |
--------------------------------------------------------------------------------
/3_cli_call.py:
--------------------------------------------------------------------------------
1 | from jnpr.junos import Device
2 |
3 | with Device(host='xxxx', user='demo', password='demo123') as dev:
4 | print (dev.cli("show version", warning=False))
5 |
--------------------------------------------------------------------------------
/4_load_text_config.py:
--------------------------------------------------------------------------------
1 | from jnpr.junos import Device
2 | from jnpr.junos.utils.config import Config
3 |
4 | dev = Device(host='xxxx', user='demo', password='demo123', gather_facts=False)
5 | dev.open()
6 |
7 | cu = Config(dev)
8 | data = """interfaces {
9 | ge-1/0/1 {
10 | description "MPLS interface";
11 | unit 0 {
12 | family mpls;
13 | }
14 | }
15 | ge-1/0/2 {
16 | description "MPLS interface";
17 | unit 0 {
18 | family mpls;
19 | }
20 | }
21 | }
22 | protocols {
23 | mpls {
24 | interface ge-1/0/1;
25 | interface ge-1/0/2;
26 | }
27 | }
28 | """
29 | cu.load(data, format='text')
30 | cu.pdiff()
31 | if cu.commit_check():
32 | cu.commit()
33 | else:
34 | cu.rollback()
35 |
--------------------------------------------------------------------------------
/5_load_xml_config.py:
--------------------------------------------------------------------------------
1 | from jnpr.junos import Device
2 | from jnpr.junos.utils.config import Config
3 |
4 | dev = Device(host='xxxx', user='demo', password='demo123', gather_facts=False)
5 | dev.open()
6 |
7 | cu = Config(dev)
8 | data = """
9 |
10 | F5-in
11 |
12 | test
13 |
14 |
15 |
16 |
17 |
18 | mpls
19 |
20 |
21 | """
22 |
23 |
24 | cu.load(data)
25 | if cu.commit_check():
26 | cu.commit()
27 | else:
28 | cu.rollback()
29 |
--------------------------------------------------------------------------------
/6_load_temp_conf.py:
--------------------------------------------------------------------------------
1 | from jnpr.junos import Device
2 | from jnpr.junos.utils.config import Config
3 | import yaml
4 |
5 | dev = Device(host='xxxx', user='demo', password='demo123', gather_facts=False)
6 | dev.open()
7 |
8 | data = yaml.load(open('protocol_data.yml'))
9 |
10 | cu = Config(dev)
11 |
12 | cu.load(template_path='protocol_temp.j2', template_vars=data, format='text')
13 | cu.pdiff()
14 | if cu.commit_check():
15 | cu.commit()
16 | else:
17 | cu.rollback()
18 |
19 | dev.close()
20 |
--------------------------------------------------------------------------------
/7_rollback_config.py:
--------------------------------------------------------------------------------
1 | from jnpr.junos import Device
2 | from jnpr.junos.utils.config import Config
3 |
4 | dev = Device(host='xxxx', user='demo', password='demo123', gather_facts=False)
5 | dev.open()
6 |
7 | cu = Config(dev)
8 | diff = cu.diff()
9 | if diff:
10 | cu.rollback()
11 | dev.close()
12 |
--------------------------------------------------------------------------------
/8_table_view.py:
--------------------------------------------------------------------------------
1 | from jnpr.junos import Device
2 | from jnpr.junos.op.routes import RouteTable
3 |
4 | dev = Device(host='xxxx', user='demo', password='demo123', gather_facts=False)
5 | dev.open()
6 |
7 | tbl = RouteTable(dev)
8 | tbl.get()
9 | #tbl.get('10.13.10.0/23', protocol='static')
10 | print tbl
11 | for item in tbl:
12 | print 'protocol:', item.protocol
13 | print 'age:', item.age
14 | print 'via:', item.via
15 | print
16 |
17 | dev.close()
18 |
--------------------------------------------------------------------------------
/9_user_defined_table.py:
--------------------------------------------------------------------------------
1 | from jnpr.junos import Device
2 | from jnpr.junos.factory.factory_loader import FactoryLoader
3 | import yaml
4 |
5 | yaml_data="""
6 | ---
7 | ArpTable:
8 | rpc: get-arp-table-information
9 | item: arp-table-entry
10 | key: mac-address
11 | view: ArpView
12 |
13 | ArpView:
14 | fields:
15 | mac_address: mac-address
16 | ip_address: ip-address
17 | interface_name: interface-name
18 | host: hostname
19 | """
20 |
21 | dev = Device(host='xxxx', user='demo', password='demo123', gather_facts=False)
22 | dev.open()
23 |
24 | globals().update(FactoryLoader().load(yaml.load(yaml_data)))
25 | arps = ArpTable(dev)
26 | arps.get()
27 | for arp in arps:
28 | print 'mac_address: ', arp.mac_address
29 | print 'ip_address: ', arp.ip_address
30 | print 'interface_name:', arp.interface_name
31 | print 'hostname:', arp.host
32 | print
33 |
34 | dev.close()
35 |
--------------------------------------------------------------------------------
/PyEZ_demo_sept.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 106,
6 | "metadata": {
7 | "collapsed": true
8 | },
9 | "outputs": [],
10 | "source": [
11 | "import logging\n",
12 | "logging.getLogger(\"paramiko\").setLevel(logging.WARNING)"
13 | ]
14 | },
15 | {
16 | "cell_type": "code",
17 | "execution_count": 35,
18 | "metadata": {
19 | "collapsed": true
20 | },
21 | "outputs": [],
22 | "source": [
23 | "from jnpr.junos import Device"
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": 36,
29 | "metadata": {
30 | "collapsed": true
31 | },
32 | "outputs": [],
33 | "source": [
34 | "from lxml import etree"
35 | ]
36 | },
37 | {
38 | "cell_type": "code",
39 | "execution_count": 40,
40 | "metadata": {
41 | "collapsed": true
42 | },
43 | "outputs": [],
44 | "source": [
45 | "#dev = Device(host='xxxx', user='demo', password='demo123', gather_facts=False)\n",
46 | "dev = Device(host='xxxx', user='demo', password='demo123')"
47 | ]
48 | },
49 | {
50 | "cell_type": "code",
51 | "execution_count": null,
52 | "metadata": {
53 | "collapsed": false
54 | },
55 | "outputs": [],
56 | "source": [
57 | "dev.open()"
58 | ]
59 | },
60 | {
61 | "cell_type": "code",
62 | "execution_count": null,
63 | "metadata": {
64 | "collapsed": false,
65 | "scrolled": true
66 | },
67 | "outputs": [],
68 | "source": [
69 | "dev.facts"
70 | ]
71 | },
72 | {
73 | "cell_type": "code",
74 | "execution_count": null,
75 | "metadata": {
76 | "collapsed": true
77 | },
78 | "outputs": [],
79 | "source": []
80 | },
81 | {
82 | "cell_type": "code",
83 | "execution_count": null,
84 | "metadata": {
85 | "collapsed": true
86 | },
87 | "outputs": [],
88 | "source": [
89 | "op = dev.rpc.get_interface_information()\n",
90 | "#op = dev.rpc.get_interface_information({'format': 'text'})\n",
91 | "#op = dev.rpc.get_interface_information(interface_name='lo0', terse=True)"
92 | ]
93 | },
94 | {
95 | "cell_type": "code",
96 | "execution_count": null,
97 | "metadata": {
98 | "collapsed": false
99 | },
100 | "outputs": [],
101 | "source": [
102 | "print etree.tostring(op)"
103 | ]
104 | },
105 | {
106 | "cell_type": "code",
107 | "execution_count": null,
108 | "metadata": {
109 | "collapsed": false
110 | },
111 | "outputs": [],
112 | "source": [
113 | "print dev.cli(\"show version\", warning=False)"
114 | ]
115 | },
116 | {
117 | "cell_type": "code",
118 | "execution_count": null,
119 | "metadata": {
120 | "collapsed": true
121 | },
122 | "outputs": [],
123 | "source": [
124 | "cnf = dev.rpc.get_config()"
125 | ]
126 | },
127 | {
128 | "cell_type": "code",
129 | "execution_count": null,
130 | "metadata": {
131 | "collapsed": false
132 | },
133 | "outputs": [],
134 | "source": [
135 | "print etree.tostring(cnf)"
136 | ]
137 | },
138 | {
139 | "cell_type": "code",
140 | "execution_count": null,
141 | "metadata": {
142 | "collapsed": true
143 | },
144 | "outputs": [],
145 | "source": [
146 | "data = dev.rpc.get_config(filter_xml=etree.XML(''))"
147 | ]
148 | },
149 | {
150 | "cell_type": "code",
151 | "execution_count": null,
152 | "metadata": {
153 | "collapsed": false
154 | },
155 | "outputs": [],
156 | "source": [
157 | "print etree.tostring(data)"
158 | ]
159 | },
160 | {
161 | "cell_type": "code",
162 | "execution_count": null,
163 | "metadata": {
164 | "collapsed": true
165 | },
166 | "outputs": [],
167 | "source": [
168 | "from jnpr.junos.utils.fs import FS"
169 | ]
170 | },
171 | {
172 | "cell_type": "code",
173 | "execution_count": null,
174 | "metadata": {
175 | "collapsed": true
176 | },
177 | "outputs": [],
178 | "source": [
179 | "fs = FS(dev)"
180 | ]
181 | },
182 | {
183 | "cell_type": "code",
184 | "execution_count": null,
185 | "metadata": {
186 | "collapsed": false
187 | },
188 | "outputs": [],
189 | "source": [
190 | "fs.ls('/var/tmp')"
191 | ]
192 | },
193 | {
194 | "cell_type": "code",
195 | "execution_count": null,
196 | "metadata": {
197 | "collapsed": false
198 | },
199 | "outputs": [],
200 | "source": [
201 | "print fs.cat('/var/tmp/nitin.log')"
202 | ]
203 | },
204 | {
205 | "cell_type": "markdown",
206 | "metadata": {},
207 | "source": [
208 | "### Playing with table/View\n",
209 | "```\n",
210 | "RouteTable:\n",
211 | " rpc: get-route-information\n",
212 | " args_key: destination\n",
213 | " item: route-table/rt \n",
214 | " key: rt-destination\n",
215 | " view: RouteTableView\n",
216 | "\n",
217 | "RouteTableView:\n",
218 | " groups:\n",
219 | " entry: rt-entry\n",
220 | " fields_entry:\n",
221 | " # fields taken from the group 'entry'\n",
222 | " protocol: protocol-name\n",
223 | " via: nh/via | nh/nh-local-interface\n",
224 | " age: { age/@seconds : int }\n",
225 | " nexthop: nh/to\n",
226 | "```"
227 | ]
228 | },
229 | {
230 | "cell_type": "code",
231 | "execution_count": null,
232 | "metadata": {
233 | "collapsed": false
234 | },
235 | "outputs": [],
236 | "source": [
237 | "from jnpr.junos.op.routes import RouteTable\n",
238 | "tbl = RouteTable(dev)\n",
239 | "tbl.get()"
240 | ]
241 | },
242 | {
243 | "cell_type": "code",
244 | "execution_count": null,
245 | "metadata": {
246 | "collapsed": false
247 | },
248 | "outputs": [],
249 | "source": [
250 | "for item in tbl:\n",
251 | " print 'protocol:', item.protocol\n",
252 | " print 'age:', item.age\n",
253 | " print 'via:', item.via\n",
254 | " print"
255 | ]
256 | },
257 | {
258 | "cell_type": "code",
259 | "execution_count": null,
260 | "metadata": {
261 | "collapsed": false
262 | },
263 | "outputs": [],
264 | "source": [
265 | "from jnpr.junos.factory.factory_loader import FactoryLoader\n",
266 | "import yaml\n",
267 | "\n",
268 | "yaml_data=\"\"\"\n",
269 | "---\n",
270 | "ArpTable:\n",
271 | " rpc: get-arp-table-information\n",
272 | " item: arp-table-entry\n",
273 | " key: mac-address\n",
274 | " view: ArpView\n",
275 | "\n",
276 | "ArpView:\n",
277 | " fields:\n",
278 | " mac_address: mac-address\n",
279 | " ip_address: ip-address\n",
280 | " interface_name: interface-name\n",
281 | "\"\"\"\n",
282 | "globals().update(FactoryLoader().load(yaml.load(yaml_data)))\n",
283 | "arps = ArpTable(dev)\n",
284 | "arps.get()\n",
285 | "for arp in arps:\n",
286 | " print 'mac_address: ', arp.mac_address\n",
287 | " print 'ip_address: ', arp.ip_address\n",
288 | " print 'interface_name:', arp.interface_name\n",
289 | " print"
290 | ]
291 | },
292 | {
293 | "cell_type": "markdown",
294 | "metadata": {},
295 | "source": [
296 | "## Loading Configs"
297 | ]
298 | },
299 | {
300 | "cell_type": "code",
301 | "execution_count": 11,
302 | "metadata": {
303 | "collapsed": true
304 | },
305 | "outputs": [],
306 | "source": [
307 | "from jnpr.junos.utils.config import Config\n",
308 | "cu = Config(dev)"
309 | ]
310 | },
311 | {
312 | "cell_type": "code",
313 | "execution_count": null,
314 | "metadata": {
315 | "collapsed": true
316 | },
317 | "outputs": [],
318 | "source": [
319 | "data = \"\"\"interfaces { \n",
320 | " ge-1/0/1 {\n",
321 | " description \"MPLS interface\";\n",
322 | " unit 0 {\n",
323 | " family mpls;\n",
324 | " } \n",
325 | " } \n",
326 | " ge-1/0/2 {\n",
327 | " description \"MPLS interface\";\n",
328 | " unit 0 {\n",
329 | " family mpls;\n",
330 | " } \n",
331 | " } \n",
332 | "}\n",
333 | "protocols {\n",
334 | " mpls { \n",
335 | " interface ge-1/0/1; \n",
336 | " interface ge-1/0/2; \n",
337 | " }\n",
338 | "}\n",
339 | "\"\"\""
340 | ]
341 | },
342 | {
343 | "cell_type": "code",
344 | "execution_count": null,
345 | "metadata": {
346 | "collapsed": false
347 | },
348 | "outputs": [],
349 | "source": [
350 | "cu.load(data, format='text')\n",
351 | "cu.commit_check()"
352 | ]
353 | },
354 | {
355 | "cell_type": "code",
356 | "execution_count": null,
357 | "metadata": {
358 | "collapsed": false
359 | },
360 | "outputs": [],
361 | "source": [
362 | "cu.load?"
363 | ]
364 | },
365 | {
366 | "cell_type": "code",
367 | "execution_count": null,
368 | "metadata": {
369 | "collapsed": false
370 | },
371 | "outputs": [],
372 | "source": [
373 | "data = \"\"\"\n",
374 | " \n",
375 | " F5-in\n",
376 | " \n",
377 | " test\n",
378 | " \n",
379 | " \n",
380 | " \n",
381 | " \n",
382 | " \n",
383 | " mpls\n",
384 | " \n",
385 | " \n",
386 | " \"\"\"\n",
387 | "\n",
388 | "\n",
389 | "cu.load(data)\n",
390 | "cu.commit_check()"
391 | ]
392 | },
393 | {
394 | "cell_type": "code",
395 | "execution_count": 5,
396 | "metadata": {
397 | "collapsed": true
398 | },
399 | "outputs": [],
400 | "source": [
401 | "xml_temp=\"\"\"\n",
402 | " \n",
403 | " all-local\n",
404 | " {% for prot in protocols %}\n",
405 | " \n",
406 | " {{ prot['name'] }}\n",
407 | " \n",
408 | " {{ prot.protocol }}\n",
409 | " \n",
410 | " \n",
411 | " \n",
412 | " \n",
413 | " {% endfor %}\n",
414 | " \n",
415 | " \"\"\"\n"
416 | ]
417 | },
418 | {
419 | "cell_type": "code",
420 | "execution_count": 6,
421 | "metadata": {
422 | "collapsed": false
423 | },
424 | "outputs": [
425 | {
426 | "name": "stdout",
427 | "output_type": "stream",
428 | "text": [
429 | "\n",
430 | " \n",
431 | " all-local\n",
432 | " \n",
433 | " \n",
434 | " 1\n",
435 | " \n",
436 | " direct\n",
437 | " \n",
438 | " \n",
439 | " \n",
440 | " \n",
441 | " \n",
442 | " \n",
443 | " 2\n",
444 | " \n",
445 | " static\n",
446 | " \n",
447 | " \n",
448 | " \n",
449 | " \n",
450 | " \n",
451 | " \n",
452 | " \n"
453 | ]
454 | }
455 | ],
456 | "source": [
457 | "from jinja2 import Template\n",
458 | "tmpl = Template(xml_temp)\n",
459 | "conf = tmpl.render(protocols=[{'name':'1', 'protocol':'direct'}, {'name':'2', 'protocol':'static'}])\n",
460 | "print conf\n",
461 | "#cu.load(str(conf))"
462 | ]
463 | },
464 | {
465 | "cell_type": "code",
466 | "execution_count": 31,
467 | "metadata": {
468 | "collapsed": false
469 | },
470 | "outputs": [
471 | {
472 | "name": "stdout",
473 | "output_type": "stream",
474 | "text": [
475 | "interfaces { \r\n",
476 | " {% for item in interfaces %}\r\n",
477 | " {{ item }} {\r\n",
478 | " description \"{{ description }}\";\r\n",
479 | " unit 0 {\r\n",
480 | " family {{ family }};\r\n",
481 | " } \r\n",
482 | " } {% endfor %} \r\n",
483 | "}\r\n",
484 | "protocols {\r\n",
485 | " mpls { \r\n",
486 | " {% for item in interfaces %} \r\n",
487 | " interface {{ item }}; \r\n",
488 | " {% endfor %} \r\n",
489 | " }\r\n",
490 | "}\r\n",
491 | "\r\n"
492 | ]
493 | }
494 | ],
495 | "source": [
496 | "%cat /Users/nitinkr/Coding/pyezex/protocol.conf"
497 | ]
498 | },
499 | {
500 | "cell_type": "code",
501 | "execution_count": 32,
502 | "metadata": {
503 | "collapsed": false
504 | },
505 | "outputs": [
506 | {
507 | "name": "stdout",
508 | "output_type": "stream",
509 | "text": [
510 | "---\r\n",
511 | "interfaces:\r\n",
512 | " - ge-1/0/1\r\n",
513 | " - ge-1/0/2\r\n",
514 | "description: 'MPLS interface'\r\n",
515 | "family: mpls\r\n"
516 | ]
517 | }
518 | ],
519 | "source": [
520 | "%cat /Users/nitinkr/Coding/pyezex/protocol_data.yml"
521 | ]
522 | },
523 | {
524 | "cell_type": "code",
525 | "execution_count": 33,
526 | "metadata": {
527 | "collapsed": false
528 | },
529 | "outputs": [
530 | {
531 | "name": "stdout",
532 | "output_type": "stream",
533 | "text": [
534 | "{'interfaces': ['ge-1/0/1', 'ge-1/0/2'], 'description': 'MPLS interface', 'family': 'mpls'}\n"
535 | ]
536 | }
537 | ],
538 | "source": [
539 | "import yaml\n",
540 | "data = yaml.load(open('/Users/nitinkr/Coding/pyezex/protocol_data.yml'))\n",
541 | "print data"
542 | ]
543 | },
544 | {
545 | "cell_type": "code",
546 | "execution_count": 34,
547 | "metadata": {
548 | "collapsed": false
549 | },
550 | "outputs": [
551 | {
552 | "name": "stdout",
553 | "output_type": "stream",
554 | "text": [
555 | "interfaces { \n",
556 | " \n",
557 | " ge-1/0/1 {\n",
558 | " description \"MPLS interface\";\n",
559 | " unit 0 {\n",
560 | " family mpls;\n",
561 | " } \n",
562 | " } \n",
563 | " ge-1/0/2 {\n",
564 | " description \"MPLS interface\";\n",
565 | " unit 0 {\n",
566 | " family mpls;\n",
567 | " } \n",
568 | " } \n",
569 | "}\n",
570 | "protocols {\n",
571 | " mpls { \n",
572 | " \n",
573 | " interface ge-1/0/1; \n",
574 | " \n",
575 | " interface ge-1/0/2; \n",
576 | " \n",
577 | " }\n",
578 | "}\n",
579 | "\n"
580 | ]
581 | }
582 | ],
583 | "source": [
584 | "from jinja2 import Template\n",
585 | "tmpl = Template(open('/Users/nitinkr/Coding/pyezex/protocol.conf').read())\n",
586 | "conf = tmpl.render(data)\n",
587 | "print conf"
588 | ]
589 | },
590 | {
591 | "cell_type": "code",
592 | "execution_count": 13,
593 | "metadata": {
594 | "collapsed": false
595 | },
596 | "outputs": [
597 | {
598 | "data": {
599 | "text/plain": [
600 | ""
601 | ]
602 | },
603 | "execution_count": 13,
604 | "metadata": {},
605 | "output_type": "execute_result"
606 | }
607 | ],
608 | "source": [
609 | "cu.load(template_path='/Users/nitinkr/Coding/pyezex/protocol.conf',\n",
610 | " template_vars=data, format='text')"
611 | ]
612 | },
613 | {
614 | "cell_type": "code",
615 | "execution_count": 14,
616 | "metadata": {
617 | "collapsed": false
618 | },
619 | "outputs": [
620 | {
621 | "name": "stdout",
622 | "output_type": "stream",
623 | "text": [
624 | "\n",
625 | "[edit interfaces]\n",
626 | "+ ge-1/0/1 {\n",
627 | "+ description \"MPLS interface\";\n",
628 | "+ unit 0 {\n",
629 | "+ family mpls;\n",
630 | "+ }\n",
631 | "+ }\n",
632 | "+ ge-1/0/2 {\n",
633 | "+ description \"MPLS interface\";\n",
634 | "+ unit 0 {\n",
635 | "+ family mpls;\n",
636 | "+ }\n",
637 | "+ }\n",
638 | "[edit]\n",
639 | "+ protocols {\n",
640 | "+ mpls {\n",
641 | "+ interface ge-1/0/1.0;\n",
642 | "+ interface ge-1/0/2.0;\n",
643 | "+ }\n",
644 | "+ }\n",
645 | "\n"
646 | ]
647 | }
648 | ],
649 | "source": [
650 | "cu.pdiff()"
651 | ]
652 | },
653 | {
654 | "cell_type": "code",
655 | "execution_count": 15,
656 | "metadata": {
657 | "collapsed": false
658 | },
659 | "outputs": [
660 | {
661 | "data": {
662 | "text/plain": [
663 | "True"
664 | ]
665 | },
666 | "execution_count": 15,
667 | "metadata": {},
668 | "output_type": "execute_result"
669 | }
670 | ],
671 | "source": [
672 | "cu.rollback()"
673 | ]
674 | },
675 | {
676 | "cell_type": "code",
677 | "execution_count": 16,
678 | "metadata": {
679 | "collapsed": false
680 | },
681 | "outputs": [
682 | {
683 | "name": "stdout",
684 | "output_type": "stream",
685 | "text": [
686 | "None\n"
687 | ]
688 | }
689 | ],
690 | "source": [
691 | "cu.pdiff()"
692 | ]
693 | },
694 | {
695 | "cell_type": "markdown",
696 | "metadata": {},
697 | "source": [
698 | "## Software\n",
699 | "\n",
700 | "```python\n",
701 | "def update_progress(dev, report):\n",
702 | " print dev.hostname, '> ', report\n",
703 | " \n",
704 | "sw.install('/var/tmp/junos-srxsme-12.1X46-D15.3-domestic.tgz', validate=True, progress=update_progress)\n",
705 | "```"
706 | ]
707 | },
708 | {
709 | "cell_type": "code",
710 | "execution_count": 19,
711 | "metadata": {
712 | "collapsed": true
713 | },
714 | "outputs": [],
715 | "source": [
716 | "from jnpr.junos.utils.sw import SW\n",
717 | "sw = SW(dev)"
718 | ]
719 | },
720 | {
721 | "cell_type": "code",
722 | "execution_count": 20,
723 | "metadata": {
724 | "collapsed": false
725 | },
726 | "outputs": [],
727 | "source": [
728 | "sw.install?"
729 | ]
730 | },
731 | {
732 | "cell_type": "code",
733 | "execution_count": null,
734 | "metadata": {
735 | "collapsed": false
736 | },
737 | "outputs": [],
738 | "source": [
739 | "dev = Device(host='xxxx', user='demo', password='demo123', gather_facts=False)\n",
740 | "dev.open()\n",
741 | "sw = SW(dev)\n",
742 | "ok = sw.install(package=r'/Users/nitinkr/Downloads/jinstall-xxxxx-domestic.tgz', progress=update_progress)\n",
743 | "if ok:\n",
744 | " print 'rebooting'\n",
745 | " sw.reboot()"
746 | ]
747 | },
748 | {
749 | "cell_type": "code",
750 | "execution_count": 21,
751 | "metadata": {
752 | "collapsed": true
753 | },
754 | "outputs": [],
755 | "source": [
756 | "from jnpr.junos.utils.scp import SCP"
757 | ]
758 | },
759 | {
760 | "cell_type": "code",
761 | "execution_count": 23,
762 | "metadata": {
763 | "collapsed": false
764 | },
765 | "outputs": [
766 | {
767 | "name": "stdout",
768 | "output_type": "stream",
769 | "text": [
770 | "Hello world\r\n"
771 | ]
772 | }
773 | ],
774 | "source": [
775 | "%cat info.txt"
776 | ]
777 | },
778 | {
779 | "cell_type": "code",
780 | "execution_count": 24,
781 | "metadata": {
782 | "collapsed": true
783 | },
784 | "outputs": [],
785 | "source": [
786 | "%rm info.txt"
787 | ]
788 | },
789 | {
790 | "cell_type": "code",
791 | "execution_count": null,
792 | "metadata": {
793 | "collapsed": false
794 | },
795 | "outputs": [],
796 | "source": [
797 | "import time\n",
798 | "from bokeh.plotting import figure, output_server, cursession, show\n",
799 | "from bokeh.models import NumeralTickFormatter\n",
800 | "\n",
801 | "from jnpr.junos import Device\n",
802 | "\n",
803 | "# prepare output to server\n",
804 | "output_server(\"animated_line\")\n",
805 | "\n",
806 | "p = figure(plot_width=600, plot_height=600)\n",
807 | "dev = Device(host='xxxx', user='demo', password='demo123', gather_facts=False, port=22)\n",
808 | "dev.open()\n",
809 | "\n",
810 | "x_tmp = [0]*5\n",
811 | "x_var = [0]*5\n",
812 | "ct = time.localtime()\n",
813 | "ct = ct.tm_hour*3600+ct.tm_min*60+ct.tm_sec\n",
814 | "op = dev.rpc.get_statistics_information(tcp=True)\n",
815 | "packets_sent_new = op.xpath('.//packets-sent')[0].text.strip()\n",
816 | "packets_recv_new = op.xpath('.//packets-received')[0].text.strip()\n",
817 | "p.line([ct, ct+2, ct+4, ct+6, ct+8], x_tmp, name='ex_line', legend = 'packets-sent')\n",
818 | "p.line([ct, ct+2, ct+4, ct+6, ct+8], x_var, name='ex_line', line_color=\"red\", legend = 'packets-recv')\n",
819 | "p.xaxis[0].formatter = NumeralTickFormatter(format='00:00:00')\n",
820 | "show(p)\n",
821 | "\n",
822 | "# create some simple animation..\n",
823 | "# first get our figure example data source\n",
824 | "renderer = p.select(dict(name=\"ex_line\"))\n",
825 | "ds1 = renderer[0].data_source\n",
826 | "ds2 = renderer[1].data_source\n",
827 | "while True:\n",
828 | " op = dev.rpc.get_statistics_information(tcp=True)\n",
829 | " packets_sent_new, packets_sent_old = op.xpath('.//packets-sent')[0].text.strip(), packets_sent_new\n",
830 | " packets_recv_new, packets_recv_old = op.xpath('.//packets-received')[0].text.strip(), packets_recv_new\n",
831 | " ct = time.localtime()\n",
832 | " ct = ct.tm_hour*3600+ct.tm_min*60+ct.tm_sec\n",
833 | " ds2.data[\"x\"] = ds1.data[\"x\"] = [ct, ct+2, ct+4, ct+6, ct+8]\n",
834 | " ds1.data[\"y\"] = ds1.data[\"y\"][1:]+[int(packets_sent_new)-int(packets_sent_old)]\n",
835 | " ds2.data[\"y\"] = ds2.data[\"y\"][1:]+[int(packets_recv_new)-int(packets_recv_old)]\n",
836 | " cursession().store_objects(ds1, ds2)\n",
837 | " time.sleep(1.5)"
838 | ]
839 | }
840 | ],
841 | "metadata": {
842 | "kernelspec": {
843 | "display_name": "Python 2",
844 | "language": "python",
845 | "name": "python2"
846 | },
847 | "language_info": {
848 | "codemirror_mode": {
849 | "name": "ipython",
850 | "version": 2
851 | },
852 | "file_extension": ".py",
853 | "mimetype": "text/x-python",
854 | "name": "python",
855 | "nbconvert_exporter": "python",
856 | "pygments_lexer": "ipython2",
857 | "version": "2.7.8"
858 | }
859 | },
860 | "nbformat": 4,
861 | "nbformat_minor": 0
862 | }
863 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## BLOGS
2 |
3 | * Junos and Python – Junos PyEZ – [Part 1](http://www.networkers.fi/blog/junos-and-python-junos-pyez-part-1/)
4 | Blogger: Jesse
5 |
6 | * Juniper's PyEZ - [Loading Configuration Changes](https://pynet.twb-tech.com/blog/juniper/juniper-pyez.html)
7 | Blogger: [Kirk Byers](https://twitter.com/kirkbyers)
8 |
9 | * Juniper's PyEZ - [Commit, Confirm, Rollback](https://pynet.twb-tech.com/blog/juniper/juniper-pyez-commit.html)
10 | Blogger: [Kirk Byers](https://twitter.com/kirkbyers)
11 |
12 | * Junos PyEZ [Installation & Initial Testing On Mac OS X](http://ethancbanks.com/2014/12/31/junos-pyez-installation-initial-testing-on-mac-os-x/)
13 | Blogger: [Ethan Banks](https://twitter.com/ecbanks)
14 |
15 | * Junos PyEZ
16 | * [Getting started with Junos PyEZ](https://stebe.info/2016/11/introduction-junos-pyez/)
17 | * [Checking BGP with PyEZ's Table/View](https://stebe.info/2016/11/checking-bgp-with-pyez-table-view/)
18 | * [Sync PREFIX-LISTS via Junos PyEZ on several routers](https://stebe.info/2016/11/sync-prefix-lists-via-junos-pyez/)
19 | * [How to get support information via junos PyEZ](https://stebe.info/2016/12/howto-get-support-information/)
20 |
21 | Blogger: [Stephan Behrens](https://twitter.com/stebe_info)
22 |
23 | ## USE CASES
24 | User's PyEZ examples for reference
25 |
26 | * Python tool to map vCenter Virtual Machines to logical interface on a Juniper Junos device
27 | https://github.com/fredriclinder/vmtrace
28 |
29 | * Deploying underlay and production networks @Riot Games
30 | http://www.ansible.com/ansible-network-infrastructure
31 | Speaker: [Adam Mills](https://twitter.com/riotgeneral)
32 |
33 |
--------------------------------------------------------------------------------
/fpc-info.py:
--------------------------------------------------------------------------------
1 | # Python PyEz script to collect the installed FPC hardware and show FPC status
2 | __author__ = "Chris Booker"
3 | import sys
4 | from jnpr.junos import Device
5 | from jnpr.junos.op.fpc import FpcHwTable
6 | from jnpr.junos.op.fpc import FpcInfoTable
7 | from getpass import getpass
8 | from pprint import pprint as pp
9 | from sys import exit
10 | from lxml import etree
11 |
12 |
13 | user = "lab"
14 |
15 | print "\nPlease provide password for user '" + user + "' on device '" + sys.argv[1] + "'."
16 | passwd = getpass()
17 |
18 | dev = Device(sys.argv[1],user=user,password=passwd)
19 | try:
20 | dev.open()
21 | print "Connected to " + sys.argv[1] + " as", (user)
22 | except:
23 | print "Connection failed. :-("
24 | print "\n** Type exit() to quit **"
25 |
26 |
27 | class style:
28 | BOLD = '\033[1m'
29 | END = '\033[0m'
30 |
31 |
32 |
33 | #print FPC hardware Table
34 | #get-chassis-inventory
35 | print "\n*************************************************************************************"
36 | print style.BOLD + "Chassis Installed FPC Details " + style.END
37 | fpcs = FpcHwTable(dev)
38 | fpcs.get()
39 | print fpcs
40 |
41 | for fpc in fpcs:
42 | print fpc.key," Description:", fpc.desc, "Model:", fpc.model,"Serial:", fpc.sn, "Part-number:", fpc.pn
43 |
44 |
45 |
46 | #invoke get fpc information
47 | print "\n*************************************************************************************"
48 | print style.BOLD + "Device FPC Status Details " + style.END
49 | jfpcs = FpcInfoTable(dev)
50 | jfpcs.get()
51 | print jfpcs
52 |
53 | for item in jfpcs:
54 | print "Slot:", item.key, "State:", item.state, "Memory Util%:", item.memory, "CPU%:", item.cpu
55 |
56 | dev.close()
57 |
--------------------------------------------------------------------------------
/generate_conf_from_template.py:
--------------------------------------------------------------------------------
1 | import yaml
2 | from jinja2 import Template
3 |
4 | data = yaml.load(open('protocol_data.yml'))
5 | print data
6 |
7 | tmpl = Template(open('/var/tmp/pyez_demo/examples/protocol_temp.j2').read())
8 | conf = tmpl.render(data)
9 | print conf
10 |
--------------------------------------------------------------------------------
/images/serial_conn.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vnitinv/pyez-examples/c4ca8c7440398495b5917548443cb754bdc10109/images/serial_conn.jpg
--------------------------------------------------------------------------------
/plot_tcp.py:
--------------------------------------------------------------------------------
1 | import time
2 | from bokeh.plotting import figure, output_server, cursession, show
3 | from bokeh.models import NumeralTickFormatter
4 |
5 | from jnpr.junos import Device
6 |
7 | # prepare output to server
8 | output_server("animated_line")
9 |
10 | p = figure(plot_width=600, plot_height=600)
11 | dev = Device(host='xxxx', user='demo', password='demo123', gather_facts=False, port=22)
12 | dev.open()
13 |
14 | x_tmp = [0]*5
15 | x_var = [0]*5
16 | ct = time.localtime()
17 | ct = ct.tm_hour*3600+ct.tm_min*60+ct.tm_sec
18 | op = dev.rpc.get_statistics_information(tcp=True)
19 | packets_sent_new = op.xpath('.//packets-sent')[0].text.strip()
20 | packets_recv_new = op.xpath('.//packets-received')[0].text.strip()
21 | p.line([ct, ct+2, ct+4, ct+6, ct+8], x_tmp, name='ex_line', legend = 'packets-sent')
22 | p.line([ct, ct+2, ct+4, ct+6, ct+8], x_var, name='ex_line', line_color="red", legend = 'packets-recv')
23 | p.xaxis[0].formatter = NumeralTickFormatter(format='00:00:00')
24 | show(p)
25 |
26 | # create some simple animation..
27 | # first get our figure example data source
28 | renderer = p.select(dict(name="ex_line"))
29 | ds1 = renderer[0].data_source
30 | ds2 = renderer[1].data_source
31 | while True:
32 | op = dev.rpc.get_statistics_information(tcp=True)
33 | packets_sent_new, packets_sent_old = op.xpath('.//packets-sent')[0].text.strip(), packets_sent_new
34 | packets_recv_new, packets_recv_old = op.xpath('.//packets-received')[0].text.strip(), packets_recv_new
35 | ct = time.localtime()
36 | ct = ct.tm_hour*3600+ct.tm_min*60+ct.tm_sec
37 | ds2.data["x"] = ds1.data["x"] = [ct, ct+2, ct+4, ct+6, ct+8]
38 | ds1.data["y"] = ds1.data["y"][1:]+[int(packets_sent_new)-int(packets_sent_old)]
39 | ds2.data["y"] = ds2.data["y"][1:]+[int(packets_recv_new)-int(packets_recv_old)]
40 | cursession().store_objects(ds1, ds2)
41 | time.sleep(1.5)
42 |
--------------------------------------------------------------------------------
/protocol_data.yml:
--------------------------------------------------------------------------------
1 | ---
2 | interfaces:
3 | - ge-1/0/1
4 | - ge-1/0/2
5 | description: 'MPLS interface'
6 | family: mpls
7 |
--------------------------------------------------------------------------------
/protocol_temp.j2:
--------------------------------------------------------------------------------
1 | interfaces {
2 | {% for item in interfaces %}
3 | {{ item }} {
4 | description "{{ description }}";
5 | unit 0 {
6 | family {{ family }};
7 | }
8 | } {% endfor %}
9 | }
10 | protocols {
11 | mpls {
12 | {% for item in interfaces %}
13 | interface {{ item }};
14 | {% endfor %}
15 | }
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/table_view_from_existing_xml_file.py:
--------------------------------------------------------------------------------
1 | from jnpr.junos.factory.factory_loader import FactoryLoader
2 | import yaml
3 |
4 | # from existing table/view
5 | from jnpr.junos.op.routes import RouteTable
6 |
7 | tbls = RouteTable(path='/var/tmp/get-route-information.xml')
8 | tbls.get()
9 | for item in tbls:
10 | print 'protocol:', item.protocol
11 | print 'age:', item.age
12 | print 'via:', item.via
13 |
14 |
15 | # From user defined table/view
16 | yaml_data="""
17 | ---
18 | RemoteVxlanTable:
19 | rpc: get-ethernet-switching-vxlan-rvtep-info
20 | item: vxlan-source-vtep-information/vxlan-remote-vtep-information
21 | key: remote-vtep-address
22 | view: RemoteVxlanView
23 |
24 | RemoteVxlanView:
25 | groups:
26 | vnis: vxlan-dynamic-information
27 | fields_vnis:
28 | vni: vxlan-format/vn-id
29 |
30 | """
31 |
32 | globals().update(FactoryLoader().load(yaml.load(yaml_data)))
33 | rvxlans = RemoteVxlanTable(path='/var/tmp/show_ethernet-switching_vxlan-tunnel-end-point_remote.xml')
34 | rvxlans.get()
35 | for rvxlan in rvxlans:
36 | print rvxlan.vni
37 |
--------------------------------------------------------------------------------
/templates/1_temp.j2:
--------------------------------------------------------------------------------
1 | interfaces {
2 | interface {{ iface_name }} {
3 | unit 0 {
4 | family ethernet-switching {
5 | port-mode access;
6 | replace:
7 | vlan {
8 | member {{ vlan_name }};
9 | }
10 | }
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/templates/create_vlans.conf:
--------------------------------------------------------------------------------
1 | vlans {
2 | {% for vlan in vlan_list %}
3 | {{ vlan.vlan_name }} {
4 | vlan-id {{ vlan.vlan_id }};
5 | }
6 | {% endfor %}
7 | }
8 |
--------------------------------------------------------------------------------
/templates/data_vars.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | host_ports:
3 | ports:
4 | - eth115/1/1
5 | - eth115/1/2
6 | host_ports_vlan:
7 | vlan_id: 11,23,44
8 | description:
9 | nome1: only port1
10 | nome2: only port2
11 | nome3: only port3
12 | nome4: only port4
13 | nome5: only port5
14 | mode:
15 | lacp: 11
16 | vpcid:
17 | domain: 14
18 |
--------------------------------------------------------------------------------
/templates/filter.j2:
--------------------------------------------------------------------------------
1 | interfaces {
2 | {% for item in iface_pattern | bracket_expansion %}
3 | {{ item }} {
4 | unit 0 {
5 | family ethernet-switching {
6 | port-mode access;
7 | replace:
8 | vlan {
9 | member {{ vlan_name }};
10 | }
11 | }
12 | }
13 | } {% endfor %}
14 | }
15 |
--------------------------------------------------------------------------------
/templates/generate_conf_from_template.py:
--------------------------------------------------------------------------------
1 | import yaml
2 | from jinja2 import Template
3 |
4 | data = yaml.load(open('data_vars.yaml'))
5 | print data
6 |
7 | tmpl = Template(open('template.j2').read())
8 | conf = tmpl.render(data)
9 | print conf
10 |
--------------------------------------------------------------------------------
/templates/main.j2:
--------------------------------------------------------------------------------
1 | ##
2 | ## This is top main file
3 | ##
4 |
5 | interfaces {
6 | {% for item in interfaces %}
7 | {{ item }} {
8 | description "{{ description }}";
9 | unit 0 {
10 | family {{ family }};
11 | }
12 | } {% endfor %}
13 | }
14 | ##
15 | ## including another jinja templete
16 | ##
17 | {% include 'users.j2' %}
18 |
19 | ##
20 | ## thats the end
21 | ##
22 |
--------------------------------------------------------------------------------
/templates/main_vlans.conf:
--------------------------------------------------------------------------------
1 | {% set state = state | default('present') %}
2 |
3 | {% if state == 'present' %}
4 | {% include 'create_vlans.conf' %}
5 | {% else %}
6 | {% include 'remove_vlans.conf' %}
7 | {% endif %}
8 |
--------------------------------------------------------------------------------
/templates/remove_vlans.conf:
--------------------------------------------------------------------------------
1 | vlans {
2 | {% for vlan in vlan_list %}
3 | delete: {{ vlan.vlan_name }}
4 | {% endfor %}
5 | }
6 |
--------------------------------------------------------------------------------
/templates/sshkeys/lakhan:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIIEpAIBAAKCAQEApdrhjuLJAb99Ftzuv/xNoeMJmoJ6eRdndmQHoxvq6M8vn2wA
3 | /N5w+HDoOT2X6VU5leat1YrXBu60JUYpuEcPuuvUfp9OgRvxWq7CL9sgFfVc99Mu
4 | dbZcwk4ReE0BFbbSoELXZoLXp6EzpyLGR45rOs8ezsnjMLOJ2+pBRNXhb9gPofhQ
5 | EHiKvuW8V1qR++1q/Q6wlUusKsg7uJ4r+lp8bISRSjvAGTpJedanEM5xHvSeyc+E
6 | n4F56hiibCZyThkncSuoMkUS2C0NkuwmSEHugm/e5xhERUseMPVxTFmX/0ZGN6NJ
7 | Vzr9FQudaa+aHCWL2/iKWAIgoxdKaOsTHddXYQIDAQABAoIBAGAtUWd+c3mkBXHg
8 | pEKImKwr8EG9MDBQNhsdXqBjbBGdM8yK4PfCNlibgM7QvOr+FOqsXlnarV7DxYtn
9 | 6IGIE8MdRpg24VtVTNx9QvZlZ3HUWxkLSYHRQnEavF66qMpivjlZCXfUoCIBBOcC
10 | 72BHYj80JHVd9XUkZ+kzKq40KQqlnNoeKLvHvbLPKFYi1Bj3O/o7fgHqSezLaWQ9
11 | hJz6aA0AyZfEf8+rCBLzM52mBPhXM6AgoemRvyE/JGYV3uOXOJd9Yx/hW5rE3WDG
12 | PcterioB6V8nqeu7lA4P+nNLcRfny7U/kzp9lWQ/eSiPsGSOSwVKP0LboQGL7dHG
13 | iwTAHxECgYEA2z8aNCQTzUkEdYon0+zcfzJCEseinlWQQ8lhW2WfpVjzLQz81rd8
14 | NmY2SVHi6qT7Rx8+/bfKSidZaB2Pfy5cnlhhbRUafRKneh38b9dlAEyi8Pt/LgF7
15 | 3No6CvnMyKcTuy+T+wT70o1WE+Sy0g9qa6QrqFDGX4zNsfrrmyXv28sCgYEAwah/
16 | uuj35rIDsMQECFHCIP9s700UPY7NtiNo1h1fRpOu/HH2TIlb1iRIdLJhOnM1sswU
17 | 8hNeNgTF0W4785J6oMNIGSDawHpRAZhRLkCaJtDkiXbCcIh7KauiT5YPbzX4zbZQ
18 | ncRMJ3kZcCMzM/X/pg3kngoth0h6lblHTCJmzAMCgYEAsg0qE6Qk7LdaxrX/KE2Y
19 | uDexjxzPhPSJ53MY/KeoIhj9y91bTGjQmEEj3yGAPfzkEFtgxZ3Hy7bvFe3Dxo55
20 | KyMtY/Aahe5rUnIduxpa7QZP4ZLtMwiDddVIA/fgBighjwfRjq76b4DWoes+Cff4
21 | /hfiWJvYrmpj9iGHy4TgqUcCgYA3dhtGm0vL7PVznV+ORmPzcVNwYUHHs2skm5V9
22 | pKHRo5/8umKQXtJHTNLXYPLJe49IanwhK/zSOaGxrgFLa4rlGag/UhJ0B1PFwiqV
23 | tXiwXyjkWXesJNoo//eXFWHMNsfPmkQSOtKYh20KmXojinMxyk7MGBwb310EHjDW
24 | FBAeowKBgQDJCJghGnAPl9hSPlkmOOdBWhStZTm00UdHh4KcId0HA62wfX+2tUa9
25 | 6pa+4lf42/0NvnM1asn6HNESmGyd9baFDrSLc5uwW1emLHzzHuhjP6huHWTVXNg3
26 | UUFtyicEUQw9QG+mGkF4p/f0Em9ZYiNdpculBJFLQPVITEOBTh9ZQA==
27 | -----END RSA PRIVATE KEY-----
28 |
--------------------------------------------------------------------------------
/templates/sshkeys/lakhan.pub:
--------------------------------------------------------------------------------
1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCl2uGO4skBv30W3O6//E2h4wmagnp5F2d2ZAejG+rozy+fbAD83nD4cOg5PZfpVTmV5q3VitcG7rQlRim4Rw+669R+n06BG/FarsIv2yAV9Vz30y51tlzCThF4TQEVttKgQtdmgtenoTOnIsZHjms6zx7OyeMws4nb6kFE1eFv2A+h+FAQeIq+5bxXWpH77Wr9DrCVS6wqyDu4niv6WnxshJFKO8AZOkl51qcQznEe9J7Jz4SfgXnqGKJsJnJOGSdxK6gyRRLYLQ2S7CZIQe6Cb97nGERFSx4w9XFMWZf/RkY3o0lXOv0VC51pr5ocJYvb+IpYAiCjF0po6xMd11dh nitinkr@nitinkr-mba13
2 |
--------------------------------------------------------------------------------
/templates/sshkeys/ram:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIIEpAIBAAKCAQEAwx0pY3PALmNlIJmbgJeYVtfFGScM4+LtULupFieGnnCu9a91
3 | a2q+uUyjYrL/3jjhVR6CPOvdCDjBxtDVMzSR/lrWhRSoSP9sl+kN1CfAobNxTiH0
4 | bzLTkb4KzeSSXykRJkVRFlXc1qhwxrOg8lw4i/IdF7AUJgiXLjEuSQovhoIGK/8r
5 | DDsy11pI4GWrI9AHFWaxpGk1dEdRHO0lfyGRjGQtUXpQ4mk4jD3bCOyxVeo52c6h
6 | vSGZjB8AywKHDvxzdp5xlFhgZ9e9ofGodH0rk5wPFpuQJw/v95PzebRzozH0VPj+
7 | +eRVpAvk8D7l67alfJIeGQVlq+Qh1LX5czZjJwIDAQABAoIBABUCgd9sqmgUWeJd
8 | yAnbyRKo31drBg9P8z/7RSTWkr9i4OQhxaIQd4MaholtPvId692vkFShDUcCXZNc
9 | D2kZIxNhkrH33Hsnzfi5pryOn0aKPQwtydVjgrax4RX0o/JNSMR3OFkQW9xdfO9Y
10 | jl8qoQgoxQs08aZ6zFS0BQjmaOGx1DANf0ZIXU6Pobml8D/llFp3/XZY5jbYoJUJ
11 | G7vUsG+ze7Jj4p5OkuqSqdLmvAvIsELJ9RTy5b9UizqsZUzdZpz+4t9NVwANWL2i
12 | kd2pYyPIti9t241guyteZWYf0ZrEk+577oEVnBWP8rihKDtd2E/g0lrxKW3WwXmA
13 | lVqHXzECgYEA+RRCdWIWSjoTaz8WKOx51ayTyvHUzYh6mXSAcQ/h1pQrxQyRqocC
14 | W0Tq4mdesC5VZMkgiyLiPo0aOUKW+mdxQyfqRLzGn1a/bY+0L0mkTO0CGnyhjH4I
15 | ue8d57EtSIPT4Knw+uyWWK/cLr0e4FZp5hNzrM7KTu7muRvUuZX2JikCgYEAyIkJ
16 | 5KZru/9elHOBksOWB54jHCf9/DDEJAbTe7N4BWTVboytjkyO1Rx2CScHv7GfD30Q
17 | nmMb0OKRVCrOJg5u8tdo+s+CJP44BopWvVJXsq2SX/kzHQuB4HRKDTcpei7Zyf08
18 | 3tUJT7rCnpAkKYzO9D0TMEFu6e/zdUOrfl0iSM8CgYAqXXrMUmmuKGCjLjDLtyUl
19 | 5duhei6S4vLPZRRvpp7oC33CX1frZFlPQtKcva5KUyctJFSHteA7eW6LbLsXTj7i
20 | iEh9dopmEbAvp3CjVmg+uVVRQf+MUOeVEInKncUw/1MrdFxLobAU15ygyoQU7j3G
21 | 52oWa3nXoSTXOVeeVVZvuQKBgQCGPW44+Mq/w5gtqhDADVu+Z7a7H25fRsnWEBe8
22 | BAzBF5nkchmwW0F2GaJOSClgwmdm9+KLFG9HapO8kxcC1MCioV5uH0DQwLkCb9LW
23 | 02tPee+1fV0hAVYEyfPUWuvSFdDG7VW1GUktbSjg+j6q7c6QIt5YfETiJzWDdzQy
24 | 1+eecwKBgQC0EOQri7Ev/CrOPswhbzC7qikr/IKoqo7CHPdPItIGVLnCbPUerlMw
25 | 8LSSrPCrlqp2ovkS5SOSDcTQIUHaw5Qiv8UnZqKGqjVJPNHYII7NOvsxMq27tTo4
26 | Tm2UgcYwVVwEFj5kiDNKTrE4G6zT0cof7NQOOCOOrqt2vAJrb5ZFrQ==
27 | -----END RSA PRIVATE KEY-----
28 |
--------------------------------------------------------------------------------
/templates/sshkeys/ram.pub:
--------------------------------------------------------------------------------
1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDHSljc8AuY2UgmZuAl5hW18UZJwzj4u1Qu6kWJ4aecK71r3Vrar65TKNisv/eOOFVHoI8690IOMHG0NUzNJH+WtaFFKhI/2yX6Q3UJ8Chs3FOIfRvMtORvgrN5JJfKREmRVEWVdzWqHDGs6DyXDiL8h0XsBQmCJcuMS5JCi+GggYr/ysMOzLXWkjgZasj0AcVZrGkaTV0R1Ec7SV/IZGMZC1RelDiaTiMPdsI7LFV6jnZzqG9IZmMHwDLAocO/HN2nnGUWGBn172h8ah0fSuTnA8Wm5AnD+/3k/N5tHOjMfRU+P755FWkC+TwPuXrtqV8kh4ZBWWr5CHUtflzNmMn nitinkr@nitinkr-mba13
2 |
--------------------------------------------------------------------------------
/templates/template.j2:
--------------------------------------------------------------------------------
1 | {% for iface in host_ports.ports %}
2 | interface {{ iface }}
3 | description {{ description.port1 }}
4 | switchport access vlan {{ host_ports_vlan.vlan_id }}
5 | no snmp trap link-status
6 | no cdp ena
7 | no lldp transmit
8 | no lldp receive
9 | spanning-tree bpduguard enable
10 | channel-group {{ mode.lacp }} mode active
11 | {% endfor %}
12 |
--------------------------------------------------------------------------------
/templates/users.j2:
--------------------------------------------------------------------------------
1 | system {
2 | login {
3 | {% for ssh_pub in sshkeyfiles %}
4 | user {{ ssh_pub | basefilename }} {
5 | authentication {
6 | ssh-rsa "{% include ssh_pub %}";
7 | }
8 | }
9 | {% endfor %}
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/templates/vlans.csv:
--------------------------------------------------------------------------------
1 | vlan_name,vlan_id
2 | Blue,100
3 | Green,200
4 | Yellow,300
5 | Purple,400
6 | Red,500
7 |
--------------------------------------------------------------------------------
/templates/yaml_jinja_demo.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 2,
6 | "metadata": {
7 | "collapsed": false
8 | },
9 | "outputs": [
10 | {
11 | "name": "stdout",
12 | "output_type": "stream",
13 | "text": [
14 | "ge-0/0/1\n"
15 | ]
16 | }
17 | ],
18 | "source": [
19 | "interface_name = 'ge-0/0/1'\n",
20 | "print interface_name"
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "metadata": {},
26 | "source": [
27 | "\n",
28 | "### Python List"
29 | ]
30 | },
31 | {
32 | "cell_type": "code",
33 | "execution_count": 9,
34 | "metadata": {
35 | "collapsed": false
36 | },
37 | "outputs": [],
38 | "source": [
39 | "protocols = ['mpls', 'bgp', 'isis', 'ospf']"
40 | ]
41 | },
42 | {
43 | "cell_type": "code",
44 | "execution_count": 10,
45 | "metadata": {
46 | "collapsed": false
47 | },
48 | "outputs": [
49 | {
50 | "name": "stdout",
51 | "output_type": "stream",
52 | "text": [
53 | "mpls\n",
54 | "bgp\n",
55 | "isis\n",
56 | "ospf\n"
57 | ]
58 | }
59 | ],
60 | "source": [
61 | "for prot in protocols:\n",
62 | " print prot"
63 | ]
64 | },
65 | {
66 | "cell_type": "markdown",
67 | "metadata": {},
68 | "source": [
69 | "### Python Dictionary"
70 | ]
71 | },
72 | {
73 | "cell_type": "code",
74 | "execution_count": 13,
75 | "metadata": {
76 | "collapsed": false
77 | },
78 | "outputs": [
79 | {
80 | "name": "stdout",
81 | "output_type": "stream",
82 | "text": [
83 | "{'ceo': 'Rami Rahim', 'company': 'Juniper', 'domain': 'Networking'}\n"
84 | ]
85 | }
86 | ],
87 | "source": [
88 | "data = {'company': 'Juniper',\n",
89 | " 'ceo': 'Rami Rahim',\n",
90 | " 'domain': 'Networking'}\n",
91 | "\n",
92 | "print data"
93 | ]
94 | },
95 | {
96 | "cell_type": "code",
97 | "execution_count": 14,
98 | "metadata": {
99 | "collapsed": false
100 | },
101 | "outputs": [
102 | {
103 | "name": "stdout",
104 | "output_type": "stream",
105 | "text": [
106 | "ceo -> Rami Rahim\n",
107 | "company -> Juniper\n",
108 | "domain -> Networking\n"
109 | ]
110 | }
111 | ],
112 | "source": [
113 | "for k,v in data.items():\n",
114 | " print k, ' -> ', v"
115 | ]
116 | },
117 | {
118 | "cell_type": "code",
119 | "execution_count": 15,
120 | "metadata": {
121 | "collapsed": false
122 | },
123 | "outputs": [
124 | {
125 | "name": "stdout",
126 | "output_type": "stream",
127 | "text": [
128 | "{'vlan_name': '200', 'iface_name': 'ge-0/0/1'}\n"
129 | ]
130 | }
131 | ],
132 | "source": [
133 | "data = {'iface_name':'ge-0/0/1', 'vlan_name':'200'}\n",
134 | "print data"
135 | ]
136 | },
137 | {
138 | "cell_type": "markdown",
139 | "metadata": {},
140 | "source": [
141 | "# YAML\n",
142 | "\n",
143 | "### YAML is a human friendly data serialization standard for all programming languages. It is ideal for storing object tree.\n",
144 | "\n",
145 | "### Python programmers are generally big fans of YAML, because of the use of indentation, rather than bracketed syntax, to indicate levels.\n",
146 | "\n",
147 | "### A markup language is a language that annotates text so that the computer can manipulate the text.\n"
148 | ]
149 | },
150 | {
151 | "cell_type": "markdown",
152 | "metadata": {},
153 | "source": [
154 | "```yaml\n",
155 | "---\n",
156 | "# An employee record\n",
157 | "name: Example Developer \n",
158 | "job: Developer \n",
159 | "skill: Elite \n",
160 | "employed: True \n",
161 | "foods: \n",
162 | " - Apple \n",
163 | " - Orange \n",
164 | " - Strawberry \n",
165 | " - Mango \n",
166 | "languages: \n",
167 | " ruby: Elite \n",
168 | " python: Elite \n",
169 | " dotnet: Lame\n",
170 | "```"
171 | ]
172 | },
173 | {
174 | "cell_type": "markdown",
175 | "metadata": {},
176 | "source": [
177 | "#### Thumb rule to write YAML: Proper indentation. "
178 | ]
179 | },
180 | {
181 | "cell_type": "markdown",
182 | "metadata": {},
183 | "source": [
184 | "So what are the benefits of YAML:\n",
185 | "\n",
186 | "Portable between programming languages:\n",
187 | "\n",
188 | "YAML emitters and parsers for many popular languages written in the pure native language itself exist, making it portable in a self-contained manner. \n",
189 | "YAML representations of application information will be consistent and portable between various programming environments\n",
190 | "\n",
191 | "Well known libraries to play with YAML in programming language:\n",
192 | "C/C++: \n",
193 | "- libyaml \t# \"C\" Fast YAML 1.1 \n",
194 | "Ruby: \n",
195 | "- Psych \t# libyaml wrapper (in Ruby core for 1.9.2) \n",
196 | "- RbYaml \t# YAML 1.1 (PyYaml Port) binding \n",
197 | "Python: \n",
198 | "- PyYaml \t# YAML 1.1, pure python and libyaml binding \n",
199 | "- PySyck \t# YAML 1.0, syck binding \n",
200 | "Java: \n",
201 | "- JvYaml \t# Java port of RbYaml \n",
202 | "Perl Modules: \n",
203 | "- YAML \t# Pure Perl YAML Module \n",
204 | "- YAML::Syck \t# Binding to libsyck \n",
205 | "- PlYaml \t# Perl port of PyYaml implementation\n",
206 | "PHP: \n",
207 | "- php-yaml \t# libyaml bindings (YAML 1.1) \n",
208 | "- syck \t# syck bindings (YAML 1.0) \n"
209 | ]
210 | },
211 | {
212 | "cell_type": "markdown",
213 | "metadata": {},
214 | "source": [
215 | "### Another example"
216 | ]
217 | },
218 | {
219 | "cell_type": "markdown",
220 | "metadata": {},
221 | "source": [
222 | "```yaml\n",
223 | "---\n",
224 | "name: Juniper Networks \n",
225 | "CEO: Rami Rahim\n",
226 | "Headquarter: Sunnyvale\n",
227 | "Development: \n",
228 | " - Sunnyvale\n",
229 | " - Bangalore\n",
230 | " - Beijing\n",
231 | "Sales: \n",
232 | " - Sydeny\n",
233 | " - Mumbai\n",
234 | "```"
235 | ]
236 | },
237 | {
238 | "cell_type": "code",
239 | "execution_count": 16,
240 | "metadata": {
241 | "collapsed": false
242 | },
243 | "outputs": [
244 | {
245 | "data": {
246 | "text/plain": [
247 | "{'CEO': 'Rami Rahim',\n",
248 | " 'Development': ['Sunnyvale', 'Bangalore', 'Beijing'],\n",
249 | " 'Headquarter': 'Sunnyvale',\n",
250 | " 'Sales': ['Sydeny', 'Mumbai'],\n",
251 | " 'name': 'Juniper Networks'}"
252 | ]
253 | },
254 | "execution_count": 16,
255 | "metadata": {},
256 | "output_type": "execute_result"
257 | }
258 | ],
259 | "source": [
260 | "import yaml\n",
261 | "\n",
262 | "data = \"\"\"\n",
263 | "---\n",
264 | "name: Juniper Networks \n",
265 | "CEO: Rami Rahim\n",
266 | "Headquarter: Sunnyvale\n",
267 | "Development: \n",
268 | " - Sunnyvale\n",
269 | " - Bangalore\n",
270 | " - Beijing\n",
271 | "Sales: \n",
272 | " - Sydeny\n",
273 | " - Mumbai\n",
274 | "\"\"\"\n",
275 | "\n",
276 | "yaml.load(data)"
277 | ]
278 | },
279 | {
280 | "cell_type": "code",
281 | "execution_count": 20,
282 | "metadata": {
283 | "collapsed": false
284 | },
285 | "outputs": [
286 | {
287 | "data": {
288 | "text/plain": [
289 | "[['pineapple', 'coconut'], ['umbrella', 'raincoat']]"
290 | ]
291 | },
292 | "execution_count": 20,
293 | "metadata": {},
294 | "output_type": "execute_result"
295 | }
296 | ],
297 | "source": [
298 | "data = \"\"\"\n",
299 | "---\n",
300 | "-\n",
301 | " - pineapple \n",
302 | " - coconut \n",
303 | "-\n",
304 | " - umbrella \n",
305 | " - raincoat\n",
306 | "\"\"\"\n",
307 | "yaml.load(data)"
308 | ]
309 | },
310 | {
311 | "cell_type": "code",
312 | "execution_count": 21,
313 | "metadata": {
314 | "collapsed": false
315 | },
316 | "outputs": [
317 | {
318 | "data": {
319 | "text/plain": [
320 | "{'Joey': {'age': 22, 'sex': 'M'}, 'Laura': {'age': 24, 'sex': 'F'}}"
321 | ]
322 | },
323 | "execution_count": 21,
324 | "metadata": {},
325 | "output_type": "execute_result"
326 | }
327 | ],
328 | "source": [
329 | "\n",
330 | "data = \"\"\"\n",
331 | "---\n",
332 | "Joey: \n",
333 | " age: 22 \n",
334 | " sex: M \n",
335 | "Laura: \n",
336 | " age: 24 \n",
337 | " sex: F\n",
338 | "\"\"\"\n",
339 | "yaml.load(data)"
340 | ]
341 | },
342 | {
343 | "cell_type": "code",
344 | "execution_count": 23,
345 | "metadata": {
346 | "collapsed": false
347 | },
348 | "outputs": [
349 | {
350 | "data": {
351 | "text/plain": [
352 | "{'bill-to': {'city': 'East Centerville',\n",
353 | " 'state': 'KS',\n",
354 | " 'street': '123 Tornado Alley\\nSuite 16\\n'},\n",
355 | " 'customer': {'family_name': 'Gale', 'first_name': 'Dorothy'},\n",
356 | " 'date': datetime.date(2012, 8, 6),\n",
357 | " 'items': [{'descrip': 'Water Bucket (Filled)',\n",
358 | " 'part_no': 'A4786',\n",
359 | " 'price': 1.47,\n",
360 | " 'quantity': 4},\n",
361 | " {'descrip': 'High Heeled \"Ruby\" Slippers',\n",
362 | " 'part_no': 'E1628',\n",
363 | " 'price': 133.7,\n",
364 | " 'quantity': 1,\n",
365 | " 'size': 8}],\n",
366 | " 'receipt': 'Oz-Ware Purchase Invoice',\n",
367 | " 'ship-to': {'city': 'East Centerville',\n",
368 | " 'state': 'KS',\n",
369 | " 'street': '123 Tornado Alley\\nSuite 16\\n'},\n",
370 | " 'specialDelivery': 'Follow the Yellow Brick\\nRoad to the Emerald City.\\nPay no attention to the\\nman behind the curtain.\\n'}"
371 | ]
372 | },
373 | "execution_count": 23,
374 | "metadata": {},
375 | "output_type": "execute_result"
376 | }
377 | ],
378 | "source": [
379 | "data = \"\"\"\n",
380 | "---\n",
381 | "receipt: Oz-Ware Purchase Invoice\n",
382 | "date: 2012-08-06\n",
383 | "customer:\n",
384 | " first_name: Dorothy\n",
385 | " family_name: Gale\n",
386 | "\n",
387 | "items:\n",
388 | " - part_no: A4786\n",
389 | " descrip: Water Bucket (Filled)\n",
390 | " price: 1.47\n",
391 | " quantity: 4\n",
392 | "\n",
393 | " - part_no: E1628\n",
394 | " descrip: High Heeled \"Ruby\" Slippers\n",
395 | " size: 8\n",
396 | " price: 133.7\n",
397 | " quantity: 1\n",
398 | "\n",
399 | "bill-to: &id001\n",
400 | " street: |\n",
401 | " 123 Tornado Alley\n",
402 | " Suite 16\n",
403 | " city: East Centerville\n",
404 | " state: KS\n",
405 | "\n",
406 | "ship-to: *id001\n",
407 | "\n",
408 | "specialDelivery: >\n",
409 | " Follow the Yellow Brick\n",
410 | " Road to the Emerald City.\n",
411 | " Pay no attention to the\n",
412 | " man behind the curtain.\n",
413 | "...\n",
414 | "\"\"\"\n",
415 | "yaml.load(data)"
416 | ]
417 | },
418 | {
419 | "cell_type": "code",
420 | "execution_count": 25,
421 | "metadata": {
422 | "collapsed": false
423 | },
424 | "outputs": [
425 | {
426 | "data": {
427 | "text/plain": [
428 | "[{'step': {'instrument': 'Lasik 2000',\n",
429 | " 'pulseDuration': 12,\n",
430 | " 'pulseEnergy': 5.4,\n",
431 | " 'repetition': 1000,\n",
432 | " 'spotSize': '1mm'}},\n",
433 | " {'step': {'instrument': 'Lasik 2000',\n",
434 | " 'pulseDuration': 10,\n",
435 | " 'pulseEnergy': 5.0,\n",
436 | " 'repetition': 500,\n",
437 | " 'spotSize': '2mm'}},\n",
438 | " {'step': {'instrument': 'Lasik 2000',\n",
439 | " 'pulseDuration': 12,\n",
440 | " 'pulseEnergy': 5.4,\n",
441 | " 'repetition': 1000,\n",
442 | " 'spotSize': '1mm'}},\n",
443 | " {'step': {'instrument': 'Lasik 2000',\n",
444 | " 'pulseDuration': 10,\n",
445 | " 'pulseEnergy': 5.0,\n",
446 | " 'repetition': 500,\n",
447 | " 'spotSize': '2mm'}},\n",
448 | " {'step': {'instrument': 'Lasik 2000',\n",
449 | " 'pulseDuration': 12,\n",
450 | " 'pulseEnergy': 5.4,\n",
451 | " 'repetition': 1000,\n",
452 | " 'spotSize': '2mm'}}]"
453 | ]
454 | },
455 | "execution_count": 25,
456 | "metadata": {},
457 | "output_type": "execute_result"
458 | }
459 | ],
460 | "source": [
461 | "data = \"\"\"\n",
462 | "---\n",
463 | "- step: &id001 # defines anchor label &id001\n",
464 | " instrument: Lasik 2000\n",
465 | " pulseEnergy: 5.4\n",
466 | " pulseDuration: 12\n",
467 | " repetition: 1000\n",
468 | " spotSize: 1mm\n",
469 | "\n",
470 | "- step: &id002\n",
471 | " instrument: Lasik 2000\n",
472 | " pulseEnergy: 5.0\n",
473 | " pulseDuration: 10\n",
474 | " repetition: 500\n",
475 | " spotSize: 2mm\n",
476 | "- step: *id001 # refers to the first step (with anchor &id001)\n",
477 | "- step: *id002 # refers to the second step\n",
478 | "- step: \n",
479 | " <<: *id001\n",
480 | " spotSize: 2mm # redefines just this key, refers rest from &id001\n",
481 | "\"\"\"\n",
482 | "yaml.load(data)"
483 | ]
484 | },
485 | {
486 | "cell_type": "code",
487 | "execution_count": 27,
488 | "metadata": {
489 | "collapsed": false
490 | },
491 | "outputs": [],
492 | "source": [
493 | "yaml.parse?"
494 | ]
495 | },
496 | {
497 | "cell_type": "markdown",
498 | "metadata": {},
499 | "source": [
500 | "## Jinja2"
501 | ]
502 | },
503 | {
504 | "cell_type": "markdown",
505 | "metadata": {},
506 | "source": [
507 | "### Junos sample config"
508 | ]
509 | },
510 | {
511 | "cell_type": "code",
512 | "execution_count": 28,
513 | "metadata": {
514 | "collapsed": false
515 | },
516 | "outputs": [
517 | {
518 | "name": "stdout",
519 | "output_type": "stream",
520 | "text": [
521 | "/Users/nitinkr/Coding/pyez-examples/templates\n"
522 | ]
523 | }
524 | ],
525 | "source": [
526 | "import os\n",
527 | "cwd = os.getcwd()\n",
528 | "print cwd"
529 | ]
530 | },
531 | {
532 | "cell_type": "code",
533 | "execution_count": 31,
534 | "metadata": {
535 | "collapsed": false
536 | },
537 | "outputs": [
538 | {
539 | "name": "stdout",
540 | "output_type": "stream",
541 | "text": [
542 | "Hello xyz!!\n"
543 | ]
544 | }
545 | ],
546 | "source": [
547 | "from jinja2 import Template\n",
548 | "t = Template(\"Hello {{ data }}!!\")\n",
549 | "print t.render(data='xyz')"
550 | ]
551 | },
552 | {
553 | "cell_type": "markdown",
554 | "metadata": {},
555 | "source": [
556 | "```text\n",
557 | "interfaces {\n",
558 | " interface ge-0/0/1 {\n",
559 | " unit 0 {\n",
560 | " family ethernet-switching {\n",
561 | " port-mode access;\n",
562 | " replace:\n",
563 | " vlan {\n",
564 | " member 200;\n",
565 | " }\n",
566 | " }\n",
567 | " }\n",
568 | " } \n",
569 | "}\n",
570 | "```\n"
571 | ]
572 | },
573 | {
574 | "cell_type": "markdown",
575 | "metadata": {},
576 | "source": [
577 | "### jinja2 template"
578 | ]
579 | },
580 | {
581 | "cell_type": "markdown",
582 | "metadata": {},
583 | "source": [
584 | "```jinja2\n",
585 | "interfaces {\n",
586 | " interface {{ iface_name }} {\n",
587 | " unit 0 {\n",
588 | " family ethernet-switching {\n",
589 | " port-mode access;\n",
590 | " replace:\n",
591 | " vlan {\n",
592 | " member {{ vlan_name }};\n",
593 | " }\n",
594 | " }\n",
595 | " }\n",
596 | " } \n",
597 | "}\n",
598 | "```\n"
599 | ]
600 | },
601 | {
602 | "cell_type": "code",
603 | "execution_count": 33,
604 | "metadata": {
605 | "collapsed": false
606 | },
607 | "outputs": [
608 | {
609 | "name": "stdout",
610 | "output_type": "stream",
611 | "text": [
612 | "interfaces {\n",
613 | " interface ge-0/0/2 {\n",
614 | " unit 0 {\n",
615 | " family ethernet-switching {\n",
616 | " port-mode access;\n",
617 | " replace:\n",
618 | " vlan {\n",
619 | " member 200;\n",
620 | " }\n",
621 | " }\n",
622 | " }\n",
623 | " } \n",
624 | "}\n"
625 | ]
626 | }
627 | ],
628 | "source": [
629 | "import jinja2\n",
630 | "template = \"\"\"interfaces {\n",
631 | " interface {{ iface_name }} {\n",
632 | " unit 0 {\n",
633 | " family ethernet-switching {\n",
634 | " port-mode access;\n",
635 | " replace:\n",
636 | " vlan {\n",
637 | " member {{ vlan_name }};\n",
638 | " }\n",
639 | " }\n",
640 | " }\n",
641 | " } \n",
642 | "}\"\"\"\n",
643 | "tmpl = jinja2.Template(template)\n",
644 | "conf = tmpl.render(iface_name='ge-0/0/2', vlan_name='200')\n",
645 | "print conf"
646 | ]
647 | },
648 | {
649 | "cell_type": "code",
650 | "execution_count": 34,
651 | "metadata": {
652 | "collapsed": false
653 | },
654 | "outputs": [
655 | {
656 | "name": "stdout",
657 | "output_type": "stream",
658 | "text": [
659 | "interfaces {\n",
660 | " interface ge-0/0/1 {\n",
661 | " unit 0 {\n",
662 | " family ethernet-switching {\n",
663 | " port-mode access;\n",
664 | " replace:\n",
665 | " vlan {\n",
666 | " member 200;\n",
667 | " }\n",
668 | " }\n",
669 | " }\n",
670 | " } \n",
671 | "}\n"
672 | ]
673 | }
674 | ],
675 | "source": [
676 | "import jinja2\n",
677 | "template = \"\"\"interfaces {\n",
678 | " interface {{ iface_name }} {\n",
679 | " unit 0 {\n",
680 | " family ethernet-switching {\n",
681 | " port-mode access;\n",
682 | " replace:\n",
683 | " vlan {\n",
684 | " member {{ vlan_name }};\n",
685 | " }\n",
686 | " }\n",
687 | " }\n",
688 | " } \n",
689 | "}\"\"\"\n",
690 | "tmpl = jinja2.Template(template)\n",
691 | "conf = tmpl.render({'iface_name':'ge-0/0/1', 'vlan_name':'200'})\n",
692 | "print conf"
693 | ]
694 | },
695 | {
696 | "cell_type": "code",
697 | "execution_count": 35,
698 | "metadata": {
699 | "collapsed": false
700 | },
701 | "outputs": [
702 | {
703 | "name": "stdout",
704 | "output_type": "stream",
705 | "text": [
706 | "interfaces {\n",
707 | " interface ge-0/0/5 {\n",
708 | " unit 0 {\n",
709 | " family ethernet-switching {\n",
710 | " port-mode access;\n",
711 | " replace:\n",
712 | " vlan {\n",
713 | " member 300;\n",
714 | " }\n",
715 | " }\n",
716 | " }\n",
717 | " } \n",
718 | "}\n"
719 | ]
720 | }
721 | ],
722 | "source": [
723 | "import jinja2\n",
724 | "\n",
725 | "# tmpl = jinja2.Template(open('/Users/nitinkr/demos/PyEZ/templates/1_temp.j2').read())\n",
726 | "\n",
727 | "loader = jinja2.FileSystemLoader(cwd)\n",
728 | "jenv = jinja2.Environment(loader=loader, trim_blocks=True, lstrip_blocks=True)\n",
729 | "tmpl = jenv.get_template('1_temp.j2')\n",
730 | "conf = tmpl.render(iface_name='ge-0/0/5', vlan_name='300')\n",
731 | "print conf"
732 | ]
733 | },
734 | {
735 | "cell_type": "markdown",
736 | "metadata": {},
737 | "source": [
738 | "#### To know more about trim_blocks, lstrip_blocks\n",
739 | "\n",
740 | "http://jinja.pocoo.org/docs/dev/templates/#whitespace-control"
741 | ]
742 | },
743 | {
744 | "cell_type": "code",
745 | "execution_count": null,
746 | "metadata": {
747 | "collapsed": false
748 | },
749 | "outputs": [],
750 | "source": [
751 | "jinja2.Environment?"
752 | ]
753 | },
754 | {
755 | "cell_type": "markdown",
756 | "metadata": {},
757 | "source": [
758 | "### Loop inside Jinja Template\n",
759 | "\n",
760 | "```jinja2\n",
761 | "interfaces {\n",
762 | " {% for item in interfaces %}\n",
763 | " {{ item }} {\n",
764 | " unit 0 {\n",
765 | " family ethernet-switching {\n",
766 | " port-mode access;\n",
767 | " replace:\n",
768 | " vlan {\n",
769 | " member {{ vlan_name }};\n",
770 | " }\n",
771 | " }\n",
772 | " } \n",
773 | " } {% endfor %} \n",
774 | "}\n",
775 | "```"
776 | ]
777 | },
778 | {
779 | "cell_type": "code",
780 | "execution_count": 37,
781 | "metadata": {
782 | "collapsed": false
783 | },
784 | "outputs": [
785 | {
786 | "name": "stdout",
787 | "output_type": "stream",
788 | "text": [
789 | "interfaces {\n",
790 | " \n",
791 | " ge-0/0/1 {\n",
792 | " unit 0 {\n",
793 | " family ethernet-switching {\n",
794 | " port-mode access;\n",
795 | " replace:\n",
796 | " vlan {\n",
797 | " member 300;\n",
798 | " }\n",
799 | " }\n",
800 | " } \n",
801 | " } \n",
802 | " ge-0/0/2 {\n",
803 | " unit 0 {\n",
804 | " family ethernet-switching {\n",
805 | " port-mode access;\n",
806 | " replace:\n",
807 | " vlan {\n",
808 | " member 300;\n",
809 | " }\n",
810 | " }\n",
811 | " } \n",
812 | " } \n",
813 | " ge-0/2/1 {\n",
814 | " unit 0 {\n",
815 | " family ethernet-switching {\n",
816 | " port-mode access;\n",
817 | " replace:\n",
818 | " vlan {\n",
819 | " member 300;\n",
820 | " }\n",
821 | " }\n",
822 | " } \n",
823 | " } \n",
824 | " ge-0/2/2 {\n",
825 | " unit 0 {\n",
826 | " family ethernet-switching {\n",
827 | " port-mode access;\n",
828 | " replace:\n",
829 | " vlan {\n",
830 | " member 300;\n",
831 | " }\n",
832 | " }\n",
833 | " } \n",
834 | " } \n",
835 | "}\n"
836 | ]
837 | }
838 | ],
839 | "source": [
840 | "import jinja2\n",
841 | "template = \"\"\"interfaces {\n",
842 | " {% for item in interfaces %}\n",
843 | " {{ item }} {\n",
844 | " unit 0 {\n",
845 | " family ethernet-switching {\n",
846 | " port-mode access;\n",
847 | " replace:\n",
848 | " vlan {\n",
849 | " member {{ vlan_name }};\n",
850 | " }\n",
851 | " }\n",
852 | " } \n",
853 | " } {% endfor %} \n",
854 | "}\"\"\"\n",
855 | "tmpl = jinja2.Template(template)\n",
856 | "conf = tmpl.render(interfaces=['ge-0/0/1', 'ge-0/0/2', 'ge-0/2/1', 'ge-0/2/2'], vlan_name='300')\n",
857 | "print conf"
858 | ]
859 | },
860 | {
861 | "cell_type": "markdown",
862 | "metadata": {},
863 | "source": [
864 | "### Filter in Template"
865 | ]
866 | },
867 | {
868 | "cell_type": "code",
869 | "execution_count": null,
870 | "metadata": {
871 | "collapsed": false
872 | },
873 | "outputs": [],
874 | "source": [
875 | "loader = jinja2.FileSystemLoader(cwd)\n",
876 | "jenv = jinja2.Environment(loader=loader, trim_blocks=True, lstrip_blocks=True)"
877 | ]
878 | },
879 | {
880 | "cell_type": "code",
881 | "execution_count": 44,
882 | "metadata": {
883 | "collapsed": false
884 | },
885 | "outputs": [
886 | {
887 | "name": "stdout",
888 | "output_type": "stream",
889 | "text": [
890 | "interfaces {\n",
891 | " \n",
892 | " ge-0/0/1 {\n",
893 | " unit 0 {\n",
894 | " family ethernet-switching {\n",
895 | " port-mode ACCESS;\n",
896 | " replace:\n",
897 | " vlan {\n",
898 | " member 300;\n",
899 | " }\n",
900 | " }\n",
901 | " } \n",
902 | " } \n",
903 | " ge-0/0/2 {\n",
904 | " unit 0 {\n",
905 | " family ethernet-switching {\n",
906 | " port-mode ACCESS;\n",
907 | " replace:\n",
908 | " vlan {\n",
909 | " member 300;\n",
910 | " }\n",
911 | " }\n",
912 | " } \n",
913 | " } \n",
914 | "}\n"
915 | ]
916 | }
917 | ],
918 | "source": [
919 | "import jinja2\n",
920 | "template = \"\"\"interfaces {\n",
921 | " {% for item in interfaces %}\n",
922 | " {{ item }} {\n",
923 | " unit 0 {\n",
924 | " family ethernet-switching {\n",
925 | " port-mode {{ mode | upper }};\n",
926 | " replace:\n",
927 | " vlan {\n",
928 | " member {{ vlan_name }};\n",
929 | " }\n",
930 | " }\n",
931 | " } \n",
932 | " } {% endfor %} \n",
933 | "}\"\"\"\n",
934 | "tmpl = jinja2.Template(template)\n",
935 | "conf = tmpl.render(interfaces=['ge-0/0/1', 'ge-0/0/2'], vlan_name='300', mode='access')\n",
936 | "print conf"
937 | ]
938 | },
939 | {
940 | "cell_type": "code",
941 | "execution_count": null,
942 | "metadata": {
943 | "collapsed": false
944 | },
945 | "outputs": [],
946 | "source": [
947 | "jenv.filters"
948 | ]
949 | },
950 | {
951 | "cell_type": "code",
952 | "execution_count": 45,
953 | "metadata": {
954 | "collapsed": false
955 | },
956 | "outputs": [
957 | {
958 | "name": "stdout",
959 | "output_type": "stream",
960 | "text": [
961 | "ge-0/0/0\n",
962 | "ge-0/0/1\n",
963 | "ge-0/0/2\n",
964 | "ge-0/0/3\n",
965 | "ge-0/0/4\n",
966 | "ge-0/0/5\n"
967 | ]
968 | }
969 | ],
970 | "source": [
971 | "from bracket_expansion import bracket_expansion\n",
972 | "jenv.filters['bracket_expansion']=bracket_expansion\n",
973 | "for i in bracket_expansion('ge-0/0/[0-5]'):\n",
974 | " print i"
975 | ]
976 | },
977 | {
978 | "cell_type": "code",
979 | "execution_count": 46,
980 | "metadata": {
981 | "collapsed": false
982 | },
983 | "outputs": [
984 | {
985 | "name": "stdout",
986 | "output_type": "stream",
987 | "text": [
988 | "interfaces {\n",
989 | " ge-0/0/0 {\n",
990 | " unit 0 {\n",
991 | " family ethernet-switching {\n",
992 | " port-mode access;\n",
993 | " replace:\n",
994 | " vlan {\n",
995 | " member 300;\n",
996 | " }\n",
997 | " }\n",
998 | " } \n",
999 | " } ge-0/0/1 {\n",
1000 | " unit 0 {\n",
1001 | " family ethernet-switching {\n",
1002 | " port-mode access;\n",
1003 | " replace:\n",
1004 | " vlan {\n",
1005 | " member 300;\n",
1006 | " }\n",
1007 | " }\n",
1008 | " } \n",
1009 | " } ge-0/0/2 {\n",
1010 | " unit 0 {\n",
1011 | " family ethernet-switching {\n",
1012 | " port-mode access;\n",
1013 | " replace:\n",
1014 | " vlan {\n",
1015 | " member 300;\n",
1016 | " }\n",
1017 | " }\n",
1018 | " } \n",
1019 | " } ge-0/0/3 {\n",
1020 | " unit 0 {\n",
1021 | " family ethernet-switching {\n",
1022 | " port-mode access;\n",
1023 | " replace:\n",
1024 | " vlan {\n",
1025 | " member 300;\n",
1026 | " }\n",
1027 | " }\n",
1028 | " } \n",
1029 | " } ge-0/0/4 {\n",
1030 | " unit 0 {\n",
1031 | " family ethernet-switching {\n",
1032 | " port-mode access;\n",
1033 | " replace:\n",
1034 | " vlan {\n",
1035 | " member 300;\n",
1036 | " }\n",
1037 | " }\n",
1038 | " } \n",
1039 | " } ge-0/0/5 {\n",
1040 | " unit 0 {\n",
1041 | " family ethernet-switching {\n",
1042 | " port-mode access;\n",
1043 | " replace:\n",
1044 | " vlan {\n",
1045 | " member 300;\n",
1046 | " }\n",
1047 | " }\n",
1048 | " } \n",
1049 | " } ge-0/0/6 {\n",
1050 | " unit 0 {\n",
1051 | " family ethernet-switching {\n",
1052 | " port-mode access;\n",
1053 | " replace:\n",
1054 | " vlan {\n",
1055 | " member 300;\n",
1056 | " }\n",
1057 | " }\n",
1058 | " } \n",
1059 | " } ge-0/0/7 {\n",
1060 | " unit 0 {\n",
1061 | " family ethernet-switching {\n",
1062 | " port-mode access;\n",
1063 | " replace:\n",
1064 | " vlan {\n",
1065 | " member 300;\n",
1066 | " }\n",
1067 | " }\n",
1068 | " } \n",
1069 | " } ge-0/0/8 {\n",
1070 | " unit 0 {\n",
1071 | " family ethernet-switching {\n",
1072 | " port-mode access;\n",
1073 | " replace:\n",
1074 | " vlan {\n",
1075 | " member 300;\n",
1076 | " }\n",
1077 | " }\n",
1078 | " } \n",
1079 | " } ge-0/0/9 {\n",
1080 | " unit 0 {\n",
1081 | " family ethernet-switching {\n",
1082 | " port-mode access;\n",
1083 | " replace:\n",
1084 | " vlan {\n",
1085 | " member 300;\n",
1086 | " }\n",
1087 | " }\n",
1088 | " } \n",
1089 | " } ge-0/0/10 {\n",
1090 | " unit 0 {\n",
1091 | " family ethernet-switching {\n",
1092 | " port-mode access;\n",
1093 | " replace:\n",
1094 | " vlan {\n",
1095 | " member 300;\n",
1096 | " }\n",
1097 | " }\n",
1098 | " } \n",
1099 | " } \n",
1100 | "}\n"
1101 | ]
1102 | }
1103 | ],
1104 | "source": [
1105 | "import jinja2\n",
1106 | "template = \"\"\"interfaces {\n",
1107 | " {% for item in iface_pattern | bracket_expansion %}\n",
1108 | " {{ item }} {\n",
1109 | " unit 0 {\n",
1110 | " family ethernet-switching {\n",
1111 | " port-mode access;\n",
1112 | " replace:\n",
1113 | " vlan {\n",
1114 | " member {{ vlan_name }};\n",
1115 | " }\n",
1116 | " }\n",
1117 | " } \n",
1118 | " } {% endfor %} \n",
1119 | "}\"\"\"\n",
1120 | "loader = jinja2.FileSystemLoader(cwd)\n",
1121 | "jenv = jinja2.Environment(loader=loader, trim_blocks=True, lstrip_blocks=True)\n",
1122 | "jenv.filters['bracket_expansion']=bracket_expansion\n",
1123 | "tmpl = jenv.get_template('filter.j2')\n",
1124 | "conf = tmpl.render(iface_pattern='ge-0/0/[0-10]', vlan_name='300')\n",
1125 | "print conf"
1126 | ]
1127 | },
1128 | {
1129 | "cell_type": "markdown",
1130 | "metadata": {},
1131 | "source": [
1132 | "### Include directive\n",
1133 | "#### To create Modular template"
1134 | ]
1135 | },
1136 | {
1137 | "cell_type": "code",
1138 | "execution_count": 49,
1139 | "metadata": {
1140 | "collapsed": false
1141 | },
1142 | "outputs": [
1143 | {
1144 | "name": "stdout",
1145 | "output_type": "stream",
1146 | "text": [
1147 | "['/Users/nitinkr/Coding/pyez-examples/templates/sshkeys/lakhan.pub', '/Users/nitinkr/Coding/pyez-examples/templates/sshkeys/ram.pub']\n"
1148 | ]
1149 | }
1150 | ],
1151 | "source": [
1152 | "from glob import glob\n",
1153 | "print glob(cwd+'/sshkeys/*.pub')"
1154 | ]
1155 | },
1156 | {
1157 | "cell_type": "code",
1158 | "execution_count": 50,
1159 | "metadata": {
1160 | "collapsed": false
1161 | },
1162 | "outputs": [
1163 | {
1164 | "name": "stdout",
1165 | "output_type": "stream",
1166 | "text": [
1167 | "['lakhan.pub', 'ram.pub']\n",
1168 | "['lakhan', 'ram']\n"
1169 | ]
1170 | }
1171 | ],
1172 | "source": [
1173 | "from os.path import basename, splitext\n",
1174 | "print [basename(i) for i in glob(cwd+'/sshkeys/*.pub')]\n",
1175 | "print [splitext(basename(i))[0] for i in glob(cwd+'/sshkeys/*.pub')]"
1176 | ]
1177 | },
1178 | {
1179 | "cell_type": "code",
1180 | "execution_count": 51,
1181 | "metadata": {
1182 | "collapsed": true
1183 | },
1184 | "outputs": [],
1185 | "source": [
1186 | "def basefilename(name):\n",
1187 | " return splitext(basename(name))[0]\n",
1188 | "\n",
1189 | "# basefilename = lambda name: splitext(basename(name))[0]"
1190 | ]
1191 | },
1192 | {
1193 | "cell_type": "markdown",
1194 | "metadata": {},
1195 | "source": [
1196 | "```jinja2\n",
1197 | "system {\n",
1198 | " login {\n",
1199 | " {% for ssh_pub in sshkeyfiles %}\n",
1200 | " user {{ ssh_pub | basefilename }} {\n",
1201 | " authentication {\n",
1202 | " ssh-rsa \"{% include ssh_pub %}\";\n",
1203 | " }\n",
1204 | " }\n",
1205 | " {% endfor %}\n",
1206 | " }\n",
1207 | "}\n",
1208 | "```"
1209 | ]
1210 | },
1211 | {
1212 | "cell_type": "code",
1213 | "execution_count": 52,
1214 | "metadata": {
1215 | "collapsed": false
1216 | },
1217 | "outputs": [
1218 | {
1219 | "name": "stdout",
1220 | "output_type": "stream",
1221 | "text": [
1222 | "system {\n",
1223 | " login {\n",
1224 | " user lakhan {\n",
1225 | " authentication {\n",
1226 | " ssh-rsa \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCl2uGO4skBv30W3O6//E2h4wmagnp5F2d2ZAejG+rozy+fbAD83nD4cOg5PZfpVTmV5q3VitcG7rQlRim4Rw+669R+n06BG/FarsIv2yAV9Vz30y51tlzCThF4TQEVttKgQtdmgtenoTOnIsZHjms6zx7OyeMws4nb6kFE1eFv2A+h+FAQeIq+5bxXWpH77Wr9DrCVS6wqyDu4niv6WnxshJFKO8AZOkl51qcQznEe9J7Jz4SfgXnqGKJsJnJOGSdxK6gyRRLYLQ2S7CZIQe6Cb97nGERFSx4w9XFMWZf/RkY3o0lXOv0VC51pr5ocJYvb+IpYAiCjF0po6xMd11dh nitinkr@nitinkr-mba13\";\n",
1227 | " }\n",
1228 | " }\n",
1229 | " user ram {\n",
1230 | " authentication {\n",
1231 | " ssh-rsa \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDHSljc8AuY2UgmZuAl5hW18UZJwzj4u1Qu6kWJ4aecK71r3Vrar65TKNisv/eOOFVHoI8690IOMHG0NUzNJH+WtaFFKhI/2yX6Q3UJ8Chs3FOIfRvMtORvgrN5JJfKREmRVEWVdzWqHDGs6DyXDiL8h0XsBQmCJcuMS5JCi+GggYr/ysMOzLXWkjgZasj0AcVZrGkaTV0R1Ec7SV/IZGMZC1RelDiaTiMPdsI7LFV6jnZzqG9IZmMHwDLAocO/HN2nnGUWGBn172h8ah0fSuTnA8Wm5AnD+/3k/N5tHOjMfRU+P755FWkC+TwPuXrtqV8kh4ZBWWr5CHUtflzNmMn nitinkr@nitinkr-mba13\";\n",
1232 | " }\n",
1233 | " }\n",
1234 | " }\n",
1235 | "}\n"
1236 | ]
1237 | }
1238 | ],
1239 | "source": [
1240 | "import jinja2\n",
1241 | "\n",
1242 | "loader = jinja2.FileSystemLoader(cwd)\n",
1243 | "jenv = jinja2.Environment(loader=loader, trim_blocks=True, lstrip_blocks=True)\n",
1244 | "jenv.filters['basefilename']=basefilename\n",
1245 | "tmpl = jenv.get_template('users.j2')\n",
1246 | "print tmpl.render(sshkeyfiles=glob('sshkeys/*.pub'))"
1247 | ]
1248 | },
1249 | {
1250 | "cell_type": "code",
1251 | "execution_count": 53,
1252 | "metadata": {
1253 | "collapsed": false
1254 | },
1255 | "outputs": [
1256 | {
1257 | "name": "stdout",
1258 | "output_type": "stream",
1259 | "text": [
1260 | "##\n",
1261 | "## This is top main file\n",
1262 | "##\n",
1263 | "\n",
1264 | "interfaces { \n",
1265 | " {% for item in interfaces %}\n",
1266 | " {{ item }} {\n",
1267 | " description \"{{ description }}\";\n",
1268 | " unit 0 {\n",
1269 | " family {{ family }};\n",
1270 | " } \n",
1271 | " } {% endfor %} \n",
1272 | "}\n",
1273 | "##\n",
1274 | "## including another jinja templete\n",
1275 | "##\n",
1276 | "{% include 'users.j2' %}\n",
1277 | "\n",
1278 | "##\n",
1279 | "## thats the end\n",
1280 | "##\n",
1281 | "\n"
1282 | ]
1283 | }
1284 | ],
1285 | "source": [
1286 | "with open(os.path.join(cwd, 'main.j2')) as fp:\n",
1287 | " print fp.read()"
1288 | ]
1289 | },
1290 | {
1291 | "cell_type": "code",
1292 | "execution_count": 54,
1293 | "metadata": {
1294 | "collapsed": false
1295 | },
1296 | "outputs": [
1297 | {
1298 | "name": "stdout",
1299 | "output_type": "stream",
1300 | "text": [
1301 | "##\n",
1302 | "## This is top main file\n",
1303 | "##\n",
1304 | "\n",
1305 | "interfaces { \n",
1306 | " ge-0/0/1 {\n",
1307 | " description \"MPLS interface\";\n",
1308 | " unit 0 {\n",
1309 | " family mpls;\n",
1310 | " } \n",
1311 | " } ge-0/0/2 {\n",
1312 | " description \"MPLS interface\";\n",
1313 | " unit 0 {\n",
1314 | " family mpls;\n",
1315 | " } \n",
1316 | " } \n",
1317 | "}\n",
1318 | "##\n",
1319 | "## including another jinja templete\n",
1320 | "##\n",
1321 | "system {\n",
1322 | " login {\n",
1323 | " user lakhan {\n",
1324 | " authentication {\n",
1325 | " ssh-rsa \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCl2uGO4skBv30W3O6//E2h4wmagnp5F2d2ZAejG+rozy+fbAD83nD4cOg5PZfpVTmV5q3VitcG7rQlRim4Rw+669R+n06BG/FarsIv2yAV9Vz30y51tlzCThF4TQEVttKgQtdmgtenoTOnIsZHjms6zx7OyeMws4nb6kFE1eFv2A+h+FAQeIq+5bxXWpH77Wr9DrCVS6wqyDu4niv6WnxshJFKO8AZOkl51qcQznEe9J7Jz4SfgXnqGKJsJnJOGSdxK6gyRRLYLQ2S7CZIQe6Cb97nGERFSx4w9XFMWZf/RkY3o0lXOv0VC51pr5ocJYvb+IpYAiCjF0po6xMd11dh nitinkr@nitinkr-mba13\";\n",
1326 | " }\n",
1327 | " }\n",
1328 | " user ram {\n",
1329 | " authentication {\n",
1330 | " ssh-rsa \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDHSljc8AuY2UgmZuAl5hW18UZJwzj4u1Qu6kWJ4aecK71r3Vrar65TKNisv/eOOFVHoI8690IOMHG0NUzNJH+WtaFFKhI/2yX6Q3UJ8Chs3FOIfRvMtORvgrN5JJfKREmRVEWVdzWqHDGs6DyXDiL8h0XsBQmCJcuMS5JCi+GggYr/ysMOzLXWkjgZasj0AcVZrGkaTV0R1Ec7SV/IZGMZC1RelDiaTiMPdsI7LFV6jnZzqG9IZmMHwDLAocO/HN2nnGUWGBn172h8ah0fSuTnA8Wm5AnD+/3k/N5tHOjMfRU+P755FWkC+TwPuXrtqV8kh4ZBWWr5CHUtflzNmMn nitinkr@nitinkr-mba13\";\n",
1331 | " }\n",
1332 | " }\n",
1333 | " }\n",
1334 | "}\n",
1335 | "##\n",
1336 | "## thats the end\n",
1337 | "##\n"
1338 | ]
1339 | }
1340 | ],
1341 | "source": [
1342 | "main = jenv.get_template('main.j2')\n",
1343 | "print main.render(sshkeyfiles=glob('sshkeys/*.pub'), interfaces=['ge-0/0/1', 'ge-0/0/2'], family='mpls', description='MPLS interface')"
1344 | ]
1345 | },
1346 | {
1347 | "cell_type": "markdown",
1348 | "metadata": {},
1349 | "source": [
1350 | "### if/then/else directives"
1351 | ]
1352 | },
1353 | {
1354 | "cell_type": "code",
1355 | "execution_count": 56,
1356 | "metadata": {
1357 | "collapsed": false
1358 | },
1359 | "outputs": [
1360 | {
1361 | "name": "stdout",
1362 | "output_type": "stream",
1363 | "text": [
1364 | "\n",
1365 | "{'vlan_id': '100', 'vlan_name': 'Blue'} ,\n",
1366 | "{'vlan_id': '200', 'vlan_name': 'Green'} ,\n",
1367 | "{'vlan_id': '300', 'vlan_name': 'Yellow'} ,\n",
1368 | "{'vlan_id': '400', 'vlan_name': 'Purple'} ,\n",
1369 | "{'vlan_id': '500', 'vlan_name': 'Red'} ,\n"
1370 | ]
1371 | }
1372 | ],
1373 | "source": [
1374 | "import csv\n",
1375 | "vlans = csv.DictReader(open(os.path.join(cwd,'vlans.csv')))\n",
1376 | "print vlans\n",
1377 | "for i in vlans:\n",
1378 | " print i,','"
1379 | ]
1380 | },
1381 | {
1382 | "cell_type": "code",
1383 | "execution_count": 57,
1384 | "metadata": {
1385 | "collapsed": false
1386 | },
1387 | "outputs": [
1388 | {
1389 | "name": "stdout",
1390 | "output_type": "stream",
1391 | "text": [
1392 | "\n",
1393 | "vlans {\n",
1394 | " Blue {\n",
1395 | " vlan-id 100;\n",
1396 | " }\n",
1397 | " Green {\n",
1398 | " vlan-id 200;\n",
1399 | " }\n",
1400 | " Yellow {\n",
1401 | " vlan-id 300;\n",
1402 | " }\n",
1403 | " Purple {\n",
1404 | " vlan-id 400;\n",
1405 | " }\n",
1406 | " Red {\n",
1407 | " vlan-id 500;\n",
1408 | " }\n",
1409 | "}\n"
1410 | ]
1411 | }
1412 | ],
1413 | "source": [
1414 | "import jinja2\n",
1415 | "\n",
1416 | "vlans = csv.DictReader(open(os.path.join(cwd,'vlans.csv')))\n",
1417 | "loader = jinja2.FileSystemLoader(cwd)\n",
1418 | "jenv = jinja2.Environment(loader=loader, trim_blocks=True, lstrip_blocks=True)\n",
1419 | "tmpl = jenv.get_template('main_vlans.conf')\n",
1420 | "print tmpl.render(vlan_list=vlans)"
1421 | ]
1422 | },
1423 | {
1424 | "cell_type": "code",
1425 | "execution_count": 58,
1426 | "metadata": {
1427 | "collapsed": false
1428 | },
1429 | "outputs": [
1430 | {
1431 | "name": "stdout",
1432 | "output_type": "stream",
1433 | "text": [
1434 | "\n",
1435 | "vlans {\n",
1436 | " delete: Blue\n",
1437 | " delete: Green\n",
1438 | " delete: Yellow\n",
1439 | " delete: Purple\n",
1440 | " delete: Red\n",
1441 | "}\n"
1442 | ]
1443 | }
1444 | ],
1445 | "source": [
1446 | "vlans = csv.DictReader(open(os.path.join(cwd,'vlans.csv')))\n",
1447 | "print tmpl.render(vlan_list=vlans, state='absent')"
1448 | ]
1449 | },
1450 | {
1451 | "cell_type": "markdown",
1452 | "metadata": {},
1453 | "source": [
1454 | "### This presentation from AnsibleFest San Francisco 2015 focused on how Riot Games utilizes Ansible, Config templates and Juniper’s Py-EZ."
1455 | ]
1456 | },
1457 | {
1458 | "cell_type": "code",
1459 | "execution_count": 59,
1460 | "metadata": {
1461 | "collapsed": false
1462 | },
1463 | "outputs": [
1464 | {
1465 | "data": {
1466 | "text/html": [
1467 | ""
1468 | ],
1469 | "text/plain": [
1470 | ""
1471 | ]
1472 | },
1473 | "execution_count": 59,
1474 | "metadata": {},
1475 | "output_type": "execute_result"
1476 | }
1477 | ],
1478 | "source": [
1479 | "from IPython.display import HTML\n",
1480 | "HTML('')"
1481 | ]
1482 | },
1483 | {
1484 | "cell_type": "code",
1485 | "execution_count": 60,
1486 | "metadata": {
1487 | "collapsed": false
1488 | },
1489 | "outputs": [
1490 | {
1491 | "data": {
1492 | "text/html": [
1493 | "\n",
1494 | " \n",
1501 | " "
1502 | ],
1503 | "text/plain": [
1504 | ""
1505 | ]
1506 | },
1507 | "execution_count": 60,
1508 | "metadata": {},
1509 | "output_type": "execute_result"
1510 | }
1511 | ],
1512 | "source": [
1513 | "from IPython.display import YouTubeVideo\n",
1514 | "YouTubeVideo('PSgSjTeqRX0', start=450, width=900, height=500)"
1515 | ]
1516 | },
1517 | {
1518 | "cell_type": "code",
1519 | "execution_count": 61,
1520 | "metadata": {
1521 | "collapsed": false
1522 | },
1523 | "outputs": [
1524 | {
1525 | "data": {
1526 | "text/html": [
1527 | "\n",
1528 | " \n",
1535 | " "
1536 | ],
1537 | "text/plain": [
1538 | ""
1539 | ]
1540 | },
1541 | "execution_count": 61,
1542 | "metadata": {},
1543 | "output_type": "execute_result"
1544 | }
1545 | ],
1546 | "source": [
1547 | "from IPython.display import YouTubeVideo\n",
1548 | "YouTubeVideo('Gk5KKozJmz8', start=156, width=900, height=500)"
1549 | ]
1550 | }
1551 | ],
1552 | "metadata": {
1553 | "kernelspec": {
1554 | "display_name": "Python 2",
1555 | "language": "python",
1556 | "name": "python2"
1557 | },
1558 | "language_info": {
1559 | "codemirror_mode": {
1560 | "name": "ipython",
1561 | "version": 2
1562 | },
1563 | "file_extension": ".py",
1564 | "mimetype": "text/x-python",
1565 | "name": "python",
1566 | "nbconvert_exporter": "python",
1567 | "pygments_lexer": "ipython2",
1568 | "version": "2.7.8"
1569 | }
1570 | },
1571 | "nbformat": 4,
1572 | "nbformat_minor": 0
1573 | }
1574 |
--------------------------------------------------------------------------------
/templates/yaml_jinja_demo.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ```python
4 | interface_name = 'ge-0/0/1'
5 | print interface_name
6 | ```
7 |
8 | ge-0/0/1
9 |
10 |
11 |
12 | ### Python List
13 |
14 |
15 | ```python
16 | protocols = ['mpls', 'bgp', 'isis', 'ospf']
17 | ```
18 |
19 |
20 | ```python
21 | for prot in protocols:
22 | print prot
23 | ```
24 |
25 | mpls
26 | bgp
27 | isis
28 | ospf
29 |
30 |
31 | ### Python Dictionary
32 |
33 |
34 | ```python
35 | data = {'company': 'Juniper',
36 | 'ceo': 'Rami Rahim',
37 | 'domain': 'Networking'}
38 |
39 | print data
40 | ```
41 |
42 | {'ceo': 'Rami Rahim', 'company': 'Juniper', 'domain': 'Networking'}
43 |
44 |
45 |
46 | ```python
47 | for k,v in data.items():
48 | print k, ' -> ', v
49 | ```
50 |
51 | ceo -> Rami Rahim
52 | company -> Juniper
53 | domain -> Networking
54 |
55 |
56 |
57 | ```python
58 | data = {'iface_name':'ge-0/0/1', 'vlan_name':'200'}
59 | print data
60 | ```
61 |
62 | {'vlan_name': '200', 'iface_name': 'ge-0/0/1'}
63 |
64 |
65 | # YAML
66 |
67 | ### YAML is a human friendly data serialization standard for all programming languages. It is ideal for storing object tree.
68 |
69 | ### Python programmers are generally big fans of YAML, because of the use of indentation, rather than bracketed syntax, to indicate levels.
70 |
71 | ### A markup language is a language that annotates text so that the computer can manipulate the text.
72 |
73 |
74 | ```yaml
75 | ---
76 | # An employee record
77 | name: Example Developer
78 | job: Developer
79 | skill: Elite
80 | employed: True
81 | foods:
82 | - Apple
83 | - Orange
84 | - Strawberry
85 | - Mango
86 | languages:
87 | ruby: Elite
88 | python: Elite
89 | dotnet: Lame
90 | ```
91 |
92 | #### Thumb rule to write YAML: Proper indentation.
93 |
94 | So what are the benefits of YAML:
95 |
96 | Portable between programming languages:
97 |
98 | YAML emitters and parsers for many popular languages written in the pure native language itself exist, making it portable in a self-contained manner.
99 | YAML representations of application information will be consistent and portable between various programming environments
100 |
101 | Well known libraries to play with YAML in programming language:
102 | C/C++:
103 | - libyaml # "C" Fast YAML 1.1
104 | Ruby:
105 | - Psych # libyaml wrapper (in Ruby core for 1.9.2)
106 | - RbYaml # YAML 1.1 (PyYaml Port) binding
107 | Python:
108 | - PyYaml # YAML 1.1, pure python and libyaml binding
109 | - PySyck # YAML 1.0, syck binding
110 | Java:
111 | - JvYaml # Java port of RbYaml
112 | Perl Modules:
113 | - YAML # Pure Perl YAML Module
114 | - YAML::Syck # Binding to libsyck
115 | - PlYaml # Perl port of PyYaml implementation
116 | PHP:
117 | - php-yaml # libyaml bindings (YAML 1.1)
118 | - syck # syck bindings (YAML 1.0)
119 |
120 |
121 | ### Another example
122 |
123 | ```yaml
124 | ---
125 | name: Juniper Networks
126 | CEO: Rami Rahim
127 | Headquarter: Sunnyvale
128 | Development:
129 | - Sunnyvale
130 | - Bangalore
131 | - Beijing
132 | Sales:
133 | - Sydeny
134 | - Mumbai
135 | ```
136 |
137 |
138 | ```python
139 | import yaml
140 |
141 | data = """
142 | ---
143 | name: Juniper Networks
144 | CEO: Rami Rahim
145 | Headquarter: Sunnyvale
146 | Development:
147 | - Sunnyvale
148 | - Bangalore
149 | - Beijing
150 | Sales:
151 | - Sydeny
152 | - Mumbai
153 | """
154 |
155 | yaml.load(data)
156 | ```
157 |
158 |
159 |
160 |
161 | {'CEO': 'Rami Rahim',
162 | 'Development': ['Sunnyvale', 'Bangalore', 'Beijing'],
163 | 'Headquarter': 'Sunnyvale',
164 | 'Sales': ['Sydeny', 'Mumbai'],
165 | 'name': 'Juniper Networks'}
166 |
167 |
168 |
169 |
170 | ```python
171 | data = """
172 | ---
173 | -
174 | - pineapple
175 | - coconut
176 | -
177 | - umbrella
178 | - raincoat
179 | """
180 | yaml.load(data)
181 | ```
182 |
183 |
184 |
185 |
186 | [['pineapple', 'coconut'], ['umbrella', 'raincoat']]
187 |
188 |
189 |
190 |
191 | ```python
192 | data = """
193 | ---
194 | Joey:
195 | age: 22
196 | sex: M
197 | Laura:
198 | age: 24
199 | sex: F
200 | """
201 | yaml.load(data)
202 | ```
203 |
204 |
205 |
206 |
207 | {'Joey': {'age': 22, 'sex': 'M'}, 'Laura': {'age': 24, 'sex': 'F'}}
208 |
209 |
210 |
211 |
212 | ```python
213 | data = """
214 | ---
215 | receipt: Oz-Ware Purchase Invoice
216 | date: 2012-08-06
217 | customer:
218 | first_name: Dorothy
219 | family_name: Gale
220 |
221 | items:
222 | - part_no: A4786
223 | descrip: Water Bucket (Filled)
224 | price: 1.47
225 | quantity: 4
226 |
227 | - part_no: E1628
228 | descrip: High Heeled "Ruby" Slippers
229 | size: 8
230 | price: 133.7
231 | quantity: 1
232 |
233 | bill-to: &id001
234 | street: |
235 | 123 Tornado Alley
236 | Suite 16
237 | city: East Centerville
238 | state: KS
239 |
240 | ship-to: *id001
241 |
242 | specialDelivery: >
243 | Follow the Yellow Brick
244 | Road to the Emerald City.
245 | Pay no attention to the
246 | man behind the curtain.
247 | ...
248 | """
249 | yaml.load(data)
250 | ```
251 |
252 |
253 |
254 |
255 | {'bill-to': {'city': 'East Centerville',
256 | 'state': 'KS',
257 | 'street': '123 Tornado Alley\nSuite 16\n'},
258 | 'customer': {'family_name': 'Gale', 'first_name': 'Dorothy'},
259 | 'date': datetime.date(2012, 8, 6),
260 | 'items': [{'descrip': 'Water Bucket (Filled)',
261 | 'part_no': 'A4786',
262 | 'price': 1.47,
263 | 'quantity': 4},
264 | {'descrip': 'High Heeled "Ruby" Slippers',
265 | 'part_no': 'E1628',
266 | 'price': 133.7,
267 | 'quantity': 1,
268 | 'size': 8}],
269 | 'receipt': 'Oz-Ware Purchase Invoice',
270 | 'ship-to': {'city': 'East Centerville',
271 | 'state': 'KS',
272 | 'street': '123 Tornado Alley\nSuite 16\n'},
273 | 'specialDelivery': 'Follow the Yellow Brick\nRoad to the Emerald City.\nPay no attention to the\nman behind the curtain.\n'}
274 |
275 |
276 |
277 |
278 | ```python
279 | data = """
280 | ---
281 | - step: &id001 # defines anchor label &id001
282 | instrument: Lasik 2000
283 | pulseEnergy: 5.4
284 | pulseDuration: 12
285 | repetition: 1000
286 | spotSize: 1mm
287 |
288 | - step: &id002
289 | instrument: Lasik 2000
290 | pulseEnergy: 5.0
291 | pulseDuration: 10
292 | repetition: 500
293 | spotSize: 2mm
294 | - step: *id001 # refers to the first step (with anchor &id001)
295 | - step: *id002 # refers to the second step
296 | - step:
297 | <<: *id001
298 | spotSize: 2mm # redefines just this key, refers rest from &id001
299 | """
300 | yaml.load(data)
301 | ```
302 |
303 |
304 |
305 |
306 | [{'step': {'instrument': 'Lasik 2000',
307 | 'pulseDuration': 12,
308 | 'pulseEnergy': 5.4,
309 | 'repetition': 1000,
310 | 'spotSize': '1mm'}},
311 | {'step': {'instrument': 'Lasik 2000',
312 | 'pulseDuration': 10,
313 | 'pulseEnergy': 5.0,
314 | 'repetition': 500,
315 | 'spotSize': '2mm'}},
316 | {'step': {'instrument': 'Lasik 2000',
317 | 'pulseDuration': 12,
318 | 'pulseEnergy': 5.4,
319 | 'repetition': 1000,
320 | 'spotSize': '1mm'}},
321 | {'step': {'instrument': 'Lasik 2000',
322 | 'pulseDuration': 10,
323 | 'pulseEnergy': 5.0,
324 | 'repetition': 500,
325 | 'spotSize': '2mm'}},
326 | {'step': {'instrument': 'Lasik 2000',
327 | 'pulseDuration': 12,
328 | 'pulseEnergy': 5.4,
329 | 'repetition': 1000,
330 | 'spotSize': '2mm'}}]
331 |
332 |
333 |
334 |
335 | ```python
336 | yaml.parse?
337 | ```
338 |
339 | ## Jinja2
340 |
341 | ### Junos sample config
342 |
343 |
344 | ```python
345 | import os
346 | cwd = os.getcwd()
347 | print cwd
348 | ```
349 |
350 | /Users/nitinkr/Coding/pyez-examples/templates
351 |
352 |
353 |
354 | ```python
355 | from jinja2 import Template
356 | t = Template("Hello {{ data }}!!")
357 | print t.render(data='xyz')
358 | ```
359 |
360 | Hello xyz!!
361 |
362 |
363 | ```text
364 | interfaces {
365 | interface ge-0/0/1 {
366 | unit 0 {
367 | family ethernet-switching {
368 | port-mode access;
369 | replace:
370 | vlan {
371 | member 200;
372 | }
373 | }
374 | }
375 | }
376 | }
377 | ```
378 |
379 |
380 | ### jinja2 template
381 |
382 | ```jinja2
383 | interfaces {
384 | interface {{ iface_name }} {
385 | unit 0 {
386 | family ethernet-switching {
387 | port-mode access;
388 | replace:
389 | vlan {
390 | member {{ vlan_name }};
391 | }
392 | }
393 | }
394 | }
395 | }
396 | ```
397 |
398 |
399 |
400 | ```python
401 | import jinja2
402 | template = """interfaces {
403 | interface {{ iface_name }} {
404 | unit 0 {
405 | family ethernet-switching {
406 | port-mode access;
407 | replace:
408 | vlan {
409 | member {{ vlan_name }};
410 | }
411 | }
412 | }
413 | }
414 | }"""
415 | tmpl = jinja2.Template(template)
416 | conf = tmpl.render(iface_name='ge-0/0/2', vlan_name='200')
417 | print conf
418 | ```
419 |
420 | interfaces {
421 | interface ge-0/0/2 {
422 | unit 0 {
423 | family ethernet-switching {
424 | port-mode access;
425 | replace:
426 | vlan {
427 | member 200;
428 | }
429 | }
430 | }
431 | }
432 | }
433 |
434 |
435 |
436 | ```python
437 | import jinja2
438 | template = """interfaces {
439 | interface {{ iface_name }} {
440 | unit 0 {
441 | family ethernet-switching {
442 | port-mode access;
443 | replace:
444 | vlan {
445 | member {{ vlan_name }};
446 | }
447 | }
448 | }
449 | }
450 | }"""
451 | tmpl = jinja2.Template(template)
452 | conf = tmpl.render({'iface_name':'ge-0/0/1', 'vlan_name':'200'})
453 | print conf
454 | ```
455 |
456 | interfaces {
457 | interface ge-0/0/1 {
458 | unit 0 {
459 | family ethernet-switching {
460 | port-mode access;
461 | replace:
462 | vlan {
463 | member 200;
464 | }
465 | }
466 | }
467 | }
468 | }
469 |
470 |
471 |
472 | ```python
473 | import jinja2
474 |
475 | # tmpl = jinja2.Template(open('/Users/nitinkr/demos/PyEZ/templates/1_temp.j2').read())
476 |
477 | loader = jinja2.FileSystemLoader(cwd)
478 | jenv = jinja2.Environment(loader=loader, trim_blocks=True, lstrip_blocks=True)
479 | tmpl = jenv.get_template('1_temp.j2')
480 | conf = tmpl.render(iface_name='ge-0/0/5', vlan_name='300')
481 | print conf
482 | ```
483 |
484 | interfaces {
485 | interface ge-0/0/5 {
486 | unit 0 {
487 | family ethernet-switching {
488 | port-mode access;
489 | replace:
490 | vlan {
491 | member 300;
492 | }
493 | }
494 | }
495 | }
496 | }
497 |
498 |
499 | #### To know more about trim_blocks, lstrip_blocks
500 |
501 | http://jinja.pocoo.org/docs/dev/templates/#whitespace-control
502 |
503 |
504 | ```python
505 | jinja2.Environment?
506 | ```
507 |
508 | ### Loop inside Jinja Template
509 |
510 | ```jinja2
511 | interfaces {
512 | {% for item in interfaces %}
513 | {{ item }} {
514 | unit 0 {
515 | family ethernet-switching {
516 | port-mode access;
517 | replace:
518 | vlan {
519 | member {{ vlan_name }};
520 | }
521 | }
522 | }
523 | } {% endfor %}
524 | }
525 | ```
526 |
527 |
528 | ```python
529 | import jinja2
530 | template = """interfaces {
531 | {% for item in interfaces %}
532 | {{ item }} {
533 | unit 0 {
534 | family ethernet-switching {
535 | port-mode access;
536 | replace:
537 | vlan {
538 | member {{ vlan_name }};
539 | }
540 | }
541 | }
542 | } {% endfor %}
543 | }"""
544 | tmpl = jinja2.Template(template)
545 | conf = tmpl.render(interfaces=['ge-0/0/1', 'ge-0/0/2', 'ge-0/2/1', 'ge-0/2/2'], vlan_name='300')
546 | print conf
547 | ```
548 |
549 | interfaces {
550 |
551 | ge-0/0/1 {
552 | unit 0 {
553 | family ethernet-switching {
554 | port-mode access;
555 | replace:
556 | vlan {
557 | member 300;
558 | }
559 | }
560 | }
561 | }
562 | ge-0/0/2 {
563 | unit 0 {
564 | family ethernet-switching {
565 | port-mode access;
566 | replace:
567 | vlan {
568 | member 300;
569 | }
570 | }
571 | }
572 | }
573 | ge-0/2/1 {
574 | unit 0 {
575 | family ethernet-switching {
576 | port-mode access;
577 | replace:
578 | vlan {
579 | member 300;
580 | }
581 | }
582 | }
583 | }
584 | ge-0/2/2 {
585 | unit 0 {
586 | family ethernet-switching {
587 | port-mode access;
588 | replace:
589 | vlan {
590 | member 300;
591 | }
592 | }
593 | }
594 | }
595 | }
596 |
597 |
598 | ### Filter in Template
599 |
600 |
601 | ```python
602 | loader = jinja2.FileSystemLoader(cwd)
603 | jenv = jinja2.Environment(loader=loader, trim_blocks=True, lstrip_blocks=True)
604 | ```
605 |
606 |
607 | ```python
608 | import jinja2
609 | template = """interfaces {
610 | {% for item in interfaces %}
611 | {{ item }} {
612 | unit 0 {
613 | family ethernet-switching {
614 | port-mode {{ mode | upper }};
615 | replace:
616 | vlan {
617 | member {{ vlan_name }};
618 | }
619 | }
620 | }
621 | } {% endfor %}
622 | }"""
623 | tmpl = jinja2.Template(template)
624 | conf = tmpl.render(interfaces=['ge-0/0/1', 'ge-0/0/2'], vlan_name='300', mode='access')
625 | print conf
626 | ```
627 |
628 | interfaces {
629 |
630 | ge-0/0/1 {
631 | unit 0 {
632 | family ethernet-switching {
633 | port-mode ACCESS;
634 | replace:
635 | vlan {
636 | member 300;
637 | }
638 | }
639 | }
640 | }
641 | ge-0/0/2 {
642 | unit 0 {
643 | family ethernet-switching {
644 | port-mode ACCESS;
645 | replace:
646 | vlan {
647 | member 300;
648 | }
649 | }
650 | }
651 | }
652 | }
653 |
654 |
655 |
656 | ```python
657 | jenv.filters
658 | ```
659 |
660 |
661 | ```python
662 | from bracket_expansion import bracket_expansion
663 | jenv.filters['bracket_expansion']=bracket_expansion
664 | for i in bracket_expansion('ge-0/0/[0-5]'):
665 | print i
666 | ```
667 |
668 | ge-0/0/0
669 | ge-0/0/1
670 | ge-0/0/2
671 | ge-0/0/3
672 | ge-0/0/4
673 | ge-0/0/5
674 |
675 |
676 |
677 | ```python
678 | import jinja2
679 | template = """interfaces {
680 | {% for item in iface_pattern | bracket_expansion %}
681 | {{ item }} {
682 | unit 0 {
683 | family ethernet-switching {
684 | port-mode access;
685 | replace:
686 | vlan {
687 | member {{ vlan_name }};
688 | }
689 | }
690 | }
691 | } {% endfor %}
692 | }"""
693 | loader = jinja2.FileSystemLoader(cwd)
694 | jenv = jinja2.Environment(loader=loader, trim_blocks=True, lstrip_blocks=True)
695 | jenv.filters['bracket_expansion']=bracket_expansion
696 | tmpl = jenv.get_template('filter.j2')
697 | conf = tmpl.render(iface_pattern='ge-0/0/[0-10]', vlan_name='300')
698 | print conf
699 | ```
700 |
701 | interfaces {
702 | ge-0/0/0 {
703 | unit 0 {
704 | family ethernet-switching {
705 | port-mode access;
706 | replace:
707 | vlan {
708 | member 300;
709 | }
710 | }
711 | }
712 | } ge-0/0/1 {
713 | unit 0 {
714 | family ethernet-switching {
715 | port-mode access;
716 | replace:
717 | vlan {
718 | member 300;
719 | }
720 | }
721 | }
722 | } ge-0/0/2 {
723 | unit 0 {
724 | family ethernet-switching {
725 | port-mode access;
726 | replace:
727 | vlan {
728 | member 300;
729 | }
730 | }
731 | }
732 | } ge-0/0/3 {
733 | unit 0 {
734 | family ethernet-switching {
735 | port-mode access;
736 | replace:
737 | vlan {
738 | member 300;
739 | }
740 | }
741 | }
742 | } ge-0/0/4 {
743 | unit 0 {
744 | family ethernet-switching {
745 | port-mode access;
746 | replace:
747 | vlan {
748 | member 300;
749 | }
750 | }
751 | }
752 | } ge-0/0/5 {
753 | unit 0 {
754 | family ethernet-switching {
755 | port-mode access;
756 | replace:
757 | vlan {
758 | member 300;
759 | }
760 | }
761 | }
762 | } ge-0/0/6 {
763 | unit 0 {
764 | family ethernet-switching {
765 | port-mode access;
766 | replace:
767 | vlan {
768 | member 300;
769 | }
770 | }
771 | }
772 | } ge-0/0/7 {
773 | unit 0 {
774 | family ethernet-switching {
775 | port-mode access;
776 | replace:
777 | vlan {
778 | member 300;
779 | }
780 | }
781 | }
782 | } ge-0/0/8 {
783 | unit 0 {
784 | family ethernet-switching {
785 | port-mode access;
786 | replace:
787 | vlan {
788 | member 300;
789 | }
790 | }
791 | }
792 | } ge-0/0/9 {
793 | unit 0 {
794 | family ethernet-switching {
795 | port-mode access;
796 | replace:
797 | vlan {
798 | member 300;
799 | }
800 | }
801 | }
802 | } ge-0/0/10 {
803 | unit 0 {
804 | family ethernet-switching {
805 | port-mode access;
806 | replace:
807 | vlan {
808 | member 300;
809 | }
810 | }
811 | }
812 | }
813 | }
814 |
815 |
816 | ### Include directive
817 | #### To create Modular template
818 |
819 |
820 | ```python
821 | from glob import glob
822 | print glob(cwd+'/sshkeys/*.pub')
823 | ```
824 |
825 | ['/Users/nitinkr/Coding/pyez-examples/templates/sshkeys/lakhan.pub', '/Users/nitinkr/Coding/pyez-examples/templates/sshkeys/ram.pub']
826 |
827 |
828 |
829 | ```python
830 | from os.path import basename, splitext
831 | print [basename(i) for i in glob(cwd+'/sshkeys/*.pub')]
832 | print [splitext(basename(i))[0] for i in glob(cwd+'/sshkeys/*.pub')]
833 | ```
834 |
835 | ['lakhan.pub', 'ram.pub']
836 | ['lakhan', 'ram']
837 |
838 |
839 |
840 | ```python
841 | def basefilename(name):
842 | return splitext(basename(name))[0]
843 |
844 | # basefilename = lambda name: splitext(basename(name))[0]
845 | ```
846 |
847 | ```jinja2
848 | system {
849 | login {
850 | {% for ssh_pub in sshkeyfiles %}
851 | user {{ ssh_pub | basefilename }} {
852 | authentication {
853 | ssh-rsa "{% include ssh_pub %}";
854 | }
855 | }
856 | {% endfor %}
857 | }
858 | }
859 | ```
860 |
861 |
862 | ```python
863 | import jinja2
864 |
865 | loader = jinja2.FileSystemLoader(cwd)
866 | jenv = jinja2.Environment(loader=loader, trim_blocks=True, lstrip_blocks=True)
867 | jenv.filters['basefilename']=basefilename
868 | tmpl = jenv.get_template('users.j2')
869 | print tmpl.render(sshkeyfiles=glob('sshkeys/*.pub'))
870 | ```
871 |
872 | system {
873 | login {
874 | user lakhan {
875 | authentication {
876 | ssh-rsa "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCl2uGO4skBv30W3O6//E2h4wmagnp5F2d2ZAejG+rozy+fbAD83nD4cOg5PZfpVTmV5q3VitcG7rQlRim4Rw+669R+n06BG/FarsIv2yAV9Vz30y51tlzCThF4TQEVttKgQtdmgtenoTOnIsZHjms6zx7OyeMws4nb6kFE1eFv2A+h+FAQeIq+5bxXWpH77Wr9DrCVS6wqyDu4niv6WnxshJFKO8AZOkl51qcQznEe9J7Jz4SfgXnqGKJsJnJOGSdxK6gyRRLYLQ2S7CZIQe6Cb97nGERFSx4w9XFMWZf/RkY3o0lXOv0VC51pr5ocJYvb+IpYAiCjF0po6xMd11dh nitinkr@nitinkr-mba13";
877 | }
878 | }
879 | user ram {
880 | authentication {
881 | ssh-rsa "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDHSljc8AuY2UgmZuAl5hW18UZJwzj4u1Qu6kWJ4aecK71r3Vrar65TKNisv/eOOFVHoI8690IOMHG0NUzNJH+WtaFFKhI/2yX6Q3UJ8Chs3FOIfRvMtORvgrN5JJfKREmRVEWVdzWqHDGs6DyXDiL8h0XsBQmCJcuMS5JCi+GggYr/ysMOzLXWkjgZasj0AcVZrGkaTV0R1Ec7SV/IZGMZC1RelDiaTiMPdsI7LFV6jnZzqG9IZmMHwDLAocO/HN2nnGUWGBn172h8ah0fSuTnA8Wm5AnD+/3k/N5tHOjMfRU+P755FWkC+TwPuXrtqV8kh4ZBWWr5CHUtflzNmMn nitinkr@nitinkr-mba13";
882 | }
883 | }
884 | }
885 | }
886 |
887 |
888 |
889 | ```python
890 | with open(os.path.join(cwd, 'main.j2')) as fp:
891 | print fp.read()
892 | ```
893 |
894 | ##
895 | ## This is top main file
896 | ##
897 |
898 | interfaces {
899 | {% for item in interfaces %}
900 | {{ item }} {
901 | description "{{ description }}";
902 | unit 0 {
903 | family {{ family }};
904 | }
905 | } {% endfor %}
906 | }
907 | ##
908 | ## including another jinja templete
909 | ##
910 | {% include 'users.j2' %}
911 |
912 | ##
913 | ## thats the end
914 | ##
915 |
916 |
917 |
918 |
919 | ```python
920 | main = jenv.get_template('main.j2')
921 | print main.render(sshkeyfiles=glob('sshkeys/*.pub'), interfaces=['ge-0/0/1', 'ge-0/0/2'], family='mpls', description='MPLS interface')
922 | ```
923 |
924 | ##
925 | ## This is top main file
926 | ##
927 |
928 | interfaces {
929 | ge-0/0/1 {
930 | description "MPLS interface";
931 | unit 0 {
932 | family mpls;
933 | }
934 | } ge-0/0/2 {
935 | description "MPLS interface";
936 | unit 0 {
937 | family mpls;
938 | }
939 | }
940 | }
941 | ##
942 | ## including another jinja templete
943 | ##
944 | system {
945 | login {
946 | user lakhan {
947 | authentication {
948 | ssh-rsa "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCl2uGO4skBv30W3O6//E2h4wmagnp5F2d2ZAejG+rozy+fbAD83nD4cOg5PZfpVTmV5q3VitcG7rQlRim4Rw+669R+n06BG/FarsIv2yAV9Vz30y51tlzCThF4TQEVttKgQtdmgtenoTOnIsZHjms6zx7OyeMws4nb6kFE1eFv2A+h+FAQeIq+5bxXWpH77Wr9DrCVS6wqyDu4niv6WnxshJFKO8AZOkl51qcQznEe9J7Jz4SfgXnqGKJsJnJOGSdxK6gyRRLYLQ2S7CZIQe6Cb97nGERFSx4w9XFMWZf/RkY3o0lXOv0VC51pr5ocJYvb+IpYAiCjF0po6xMd11dh nitinkr@nitinkr-mba13";
949 | }
950 | }
951 | user ram {
952 | authentication {
953 | ssh-rsa "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDHSljc8AuY2UgmZuAl5hW18UZJwzj4u1Qu6kWJ4aecK71r3Vrar65TKNisv/eOOFVHoI8690IOMHG0NUzNJH+WtaFFKhI/2yX6Q3UJ8Chs3FOIfRvMtORvgrN5JJfKREmRVEWVdzWqHDGs6DyXDiL8h0XsBQmCJcuMS5JCi+GggYr/ysMOzLXWkjgZasj0AcVZrGkaTV0R1Ec7SV/IZGMZC1RelDiaTiMPdsI7LFV6jnZzqG9IZmMHwDLAocO/HN2nnGUWGBn172h8ah0fSuTnA8Wm5AnD+/3k/N5tHOjMfRU+P755FWkC+TwPuXrtqV8kh4ZBWWr5CHUtflzNmMn nitinkr@nitinkr-mba13";
954 | }
955 | }
956 | }
957 | }
958 | ##
959 | ## thats the end
960 | ##
961 |
962 |
963 | ### if/then/else directives
964 |
965 |
966 | ```python
967 | import csv
968 | vlans = csv.DictReader(open(os.path.join(cwd,'vlans.csv')))
969 | print vlans
970 | for i in vlans:
971 | print i,','
972 | ```
973 |
974 |
975 | {'vlan_id': '100', 'vlan_name': 'Blue'} ,
976 | {'vlan_id': '200', 'vlan_name': 'Green'} ,
977 | {'vlan_id': '300', 'vlan_name': 'Yellow'} ,
978 | {'vlan_id': '400', 'vlan_name': 'Purple'} ,
979 | {'vlan_id': '500', 'vlan_name': 'Red'} ,
980 |
981 |
982 |
983 | ```python
984 | import jinja2
985 |
986 | vlans = csv.DictReader(open(os.path.join(cwd,'vlans.csv')))
987 | loader = jinja2.FileSystemLoader(cwd)
988 | jenv = jinja2.Environment(loader=loader, trim_blocks=True, lstrip_blocks=True)
989 | tmpl = jenv.get_template('main_vlans.conf')
990 | print tmpl.render(vlan_list=vlans)
991 | ```
992 |
993 |
994 | vlans {
995 | Blue {
996 | vlan-id 100;
997 | }
998 | Green {
999 | vlan-id 200;
1000 | }
1001 | Yellow {
1002 | vlan-id 300;
1003 | }
1004 | Purple {
1005 | vlan-id 400;
1006 | }
1007 | Red {
1008 | vlan-id 500;
1009 | }
1010 | }
1011 |
1012 |
1013 |
1014 | ```python
1015 | vlans = csv.DictReader(open(os.path.join(cwd,'vlans.csv')))
1016 | print tmpl.render(vlan_list=vlans, state='absent')
1017 | ```
1018 |
1019 |
1020 | vlans {
1021 | delete: Blue
1022 | delete: Green
1023 | delete: Yellow
1024 | delete: Purple
1025 | delete: Red
1026 | }
1027 |
1028 |
1029 | ### This presentation from AnsibleFest San Francisco 2015 focused on how Riot Games utilizes Ansible, Config templates and Juniper’s Py-EZ.
1030 |
1031 |
1032 | ```python
1033 | from IPython.display import HTML
1034 | HTML('')
1035 | ```
1036 |
1037 |
1038 |
1039 |
1040 |
1041 |
1042 |
1043 |
1044 |
1045 | ```python
1046 | from IPython.display import YouTubeVideo
1047 | YouTubeVideo('PSgSjTeqRX0', start=450, width=900, height=500)
1048 | ```
1049 |
1050 |
1051 |
1052 |
1053 |
1054 |
1061 |
1062 |
1063 |
1064 |
1065 |
1066 | ```python
1067 | from IPython.display import YouTubeVideo
1068 | YouTubeVideo('Gk5KKozJmz8', start=156, width=900, height=500)
1069 | ```
1070 |
1071 |
1072 |
1073 |
1074 |
1075 |
1082 |
1083 |
1084 |
1085 |
--------------------------------------------------------------------------------