α αα α!
ααααΈαααα α’ααααααα½αααΆαααα
α‘αΎααα
ααΈααα
αααβαα·αβαααβααΆβαααβααΈβαα½αβαααααΆααβααΆαααΆαβαααβαααβααα αααααΎαααααΌαααααΌαααΆαα’αα»ααααααΆα αααΎαααααΆααα»α ansible αααα 1.x.x. αααβαααβααααβααΉαβααααΌαβααΆαβααβααααΎβααΆααβα αΎαβα ααα»βαααβα αΎαβααΆαβα ααααβααΆααβααΆαα·α αα α αααα»ααααααΆ ααΆααα·α αα αααα½αααΆαα·αααΎαα‘αΎαααΉαααΆααααΌα αααααααααααΌαααΆαααααΎαα αα α»ααααααααΆα ansible. α αΎαααΆααααααααα’αααααααΌαααΆαααΎααα αααααααααΆααααααΆαα α¬αααααααΆααα ααααααΆαααΆααααα αααααααΈαα½α αααααΎα configs αααααααααΎαααΆααααΆαα αααΆαα ααααΆαααα’ ααΈαα αΆ α’ αααΆαααΈαααααΌαααΆααααααΎαα‘αΎαααΆααΌαααα αΎαα ααα»ααααβαααααβααΈβααΈαβαααβααΆααβα ααβααΆαβαααααβααΆβααααααΆβααΆαβα±ααβααΆαβααΆαβααααΆααβααα’αΎαα α αΎαα αΆααααΆααααΈαααα»αααααΌααααα αα config ααΈα ααααΆααααα§αααααααααααα αααα§ααααααααααααα·ααα α ααααΆαααΆααααΆααααΈα‘αΌαααααα ααΆαααααΎα§ααααααααααΊαα½αα±αααα»αααααα·α α
αα ααΈααααααα»αααααΌαααααα½αααααΆααααΆααΆααα·αααααΆαααααααΆαααααααα»αααααααΆαααα·ααα αααα»αααΆαααααααΆαααααΆαααααΆαααααααααα»α ansibleααΆαααΆαααααααΆαααααααΆα α αΎαααα, ααααα·ααΈααα, ααΊααΆα ααα»α ααααΆαααα½αα ansible ααΊααΆαααααααΆα ααααα‘ααααΆαααααα»αααα ααααααΉααααααααα½αααΆαα½αααΉα DSL (Domain Specific Language) αααααααα½ααααααααΌααααααααΆαα ααααα·ααααααΆααααα»αα α·αααα αααα αΎα αααααα ansible ααΆβαααα»αβα’αα·ααααβαααΆαβααΆααβαα αα α αΎαβαααβααααΆαβααΆαβαα·α αΆαααΆβαα·αααβαααααΆααβααΆαβααααΌαβααααΆβααβααααα ααΆβαα·αβααααααβαααα»αβα α·αααβα‘αΎαα
ααΌα
αααααα·αααΌαααα»ααααΆααα ααααααΈααΈααααααααααΌαααΆαα’αα»ααααα ααΎααααα αααααααΆααα¬ααΆααΆααα
ααΎααααααααααααααΆαααααααα
αααα»α αααααααΆαα αα·ααααααΆααα αααααααΆαα ααΆαα α
ααΌα αααα - ααα·ααα ααΊααΆ microframework αααααααΌαααΆαααααααα αααα»α αααααααΆαα αα·ααααααΆααα αααααααΆαα αα·αααααΌαααΆααα ααΆα‘αΎααααααΆααααααααααααααα·ααααα ααΌα ααααΆααΉαααααΈααΆαα½α ansibleααΎααααΈαααααααΆααααα αΆαα ααΈααα ααΆααααα ααα·ααααααααΆαααααααα·α αα ααΊααααΌαααΆαααΆαααΆα, i.e. ααΆαααΎααααααααααΆαααΈα αα·ααααΆαααΆαααααααααααα½ααα ααα»ααααααααααΈααα·αααααΌαααΆαααααααα αααα»α DSL ααΆα ααααα‘ααααααα ααα»αααααα αααα»αααΌα ααααΆααααα·αα αΆααααΆαα ααα»ααααααα’ααΆαα p[i|i]ton α
ααΌααααα‘ααααΎαα’αααΈαααααΆαααα»αααααΎα§ααΆα αααααααΆααααΆααααααα
αααα»αααΆααααααΆαααΆααΆαααααΆαααΆαα·ααΆαααααΆαααα·αααΌααΆααααααααα ααΆαα·ααΆαααααΈαα½ααααΆαααααααα WAN ααααα·ααααααΆαααααΆααααααααΆα αααΎαααΈααααα·ααααα·ααααααααααααΆα αα·ααΈααΆαααΆαααααΌαααΊ BGP α ααααααα WAN ααΆαααΈαααααααααΊ Cisco ISG α¬ Juniper SRX α
α₯α‘αΌααααααΆααα·α αα α α’αααααααΌαααααααα ααΆαααααααααααααΆαααααααα·αααααααΉαααααααααααΆααααΆαααααΆαααΎαααΈααα’αΌαα ααΎα αααααΆα ααααα‘αααα ααΎααααααα WAN ααΆααα’αααααααααΆαααΆααΆ - ααααααααααΆααααααΆαααααααα αααα»α BGP - αααααααΆααααααααααΏαααα αααααααα·αααααααΉααααααα
ααΆααααΌα ααΎαααααΌααααα αααααΌαα½αα ααα½α αααααααΎααΌαααααΆαααααΆαααααααα ααΆαααααααααααααΉαααααΌααααααΎαααΆα ααααα‘αααααααΆαα Cisco αα·α Juniper α ααΆααα αΆαααΆα αααααααααα»αααΆααααα ααα·αααααααααααΆααα ααα»α ααΈαα½αα αα·ααααΆαααΆααααααααααΆααααααΆαα i.e. αααααΌαααΆαααΎαααααααΌα ααααΆα
ααααΌαα½α ααΆαααααααΆαα Ciscoα
$ cat templates/ios/base.j2
class-map match-all VIDEO_SURV
match access-group 111
policy-map VIDEO_SURV
class VIDEO_SURV
police 1500000 conform-action transmit exceed-action drop
interface {{ host.task_data.ifname }}
description VIDEOSURV
ip address 10.10.{{ host.task_data.ipsuffix }}.254 255.255.255.0
service-policy input VIDEO_SURV
router bgp {{ host.task_data.asn }}
network 10.40.{{ host.task_data.ipsuffix }}.0 mask 255.255.255.0
access-list 11 permit 10.10.{{ host.task_data.ipsuffix }}.0 0.0.0.255
access-list 111 permit ip 10.10.{{ host.task_data.ipsuffix }}.0 0.0.0.255 any
ααααΌαααααΆαα Juniperα
$ cat templates/junos/base.j2
set interfaces {{ host.task_data.ifname }} unit 0 description "Video surveillance"
set interfaces {{ host.task_data.ifname }} unit 0 family inet filter input limit-in
set interfaces {{ host.task_data.ifname }} unit 0 family inet address 10.10.{{ host.task_data.ipsuffix }}.254/24
set policy-options policy-statement export2bgp term 1 from route-filter 10.10.{{ host.task_data.ipsuffix }}.0/24 exact
set security zones security-zone WAN interfaces {{ host.task_data.ifname }}
set firewall policer policer-1m if-exceeding bandwidth-limit 1m
set firewall policer policer-1m if-exceeding burst-size-limit 187k
set firewall policer policer-1m then discard
set firewall policer policer-1.5m if-exceeding bandwidth-limit 1500000
set firewall policer policer-1.5m if-exceeding burst-size-limit 280k
set firewall policer policer-1.5m then discard
set firewall filter limit-in term 1 then policer policer-1.5m
set firewall filter limit-in term 1 then count limiter
ααΆααΆααα·αααΆααααααΌαα·αα ααααΈαααααααααΎαααα ααΆαααααααΊααΆααΆααα»αααααΆααααΆαααααΆαααΆαααααααα ααΆααααααααααΆαααΆααααααΆα αα·ααααααΆααααΈααΆααααααααΆαααΆααα·α αα αα ααΎαααααααααΆααααΆααααΈααααααΌαααααααααααααΆα
ααΈααααΌααααααΎα ααΎαααΎαααΆ ααΎααααΈαααααααΆααααα αΆ ααΎαααααΌαααΆααααααΆαααΆααααααααΈααααααΆαα Juniper αα·α 3 αααΆαααΆαααααααααααΆαα Cisco α αα½ααααα ααΈαααα
- ifname
- ipsuffix
- α’αα
α₯α‘αΌααααααΎαααααΌαααααααααΆαααΆααααααααΆααααααααααΆααα§αααααααΈαα½αα i.e. ααααΎααΏαααΌα ααααΆα ααΆαααΎααααα.
αααααΆαα ααΆαααΎααααα ααΎαααΉαα’αα»ααααααΆαα―αααΆααααΆαααΉααααΉα
αααααΊ α αΌαααΎααααααΎααααααα―αααΆαααΌα ααααΆα
.
βββ config.yaml
βββ inventory
β βββ defaults.yaml
β βββ groups.yaml
β βββ hosts.yaml
α―αααΆα config.yaml ααΊααΆα―αααΆαααααααα ααΆαααααααα nonir αααααααΆα
$ cat config.yaml
---
core:
num_workers: 10
inventory:
plugin: nornir.plugins.inventory.simple.SimpleInventory
options:
host_file: "inventory/hosts.yaml"
group_file: "inventory/groups.yaml"
defaults_file: "inventory/defaults.yaml"
ααΎαααΉαα ααα’α»ααααα αΆααααΆαααΆααααααααααΆαααα αααα»αα―αααΆα hosts.yaml, αααα»α (αααα»αααααΈαααααααα»αααΆαααααααΊααΆααΆαα αΌα / ααΆααααααααΆαα) αα αααα»α αααα»α.yamlαα·ααααα»αα defaults.yaml ααΎαααΉααα·ααααα αΆαα’αααΈααααα ααα»ααααα’αααααααΌααααα αΌα minuses ααΈαα ααΈααα - αααα αΆαααΆααΆααΊ αααΆαα α―αααΆαααΊαααα
αααααΆα’αααΈααα hosts.yaml ααΎααα α
---
srx-test:
hostname: srx-test
groups:
- juniper
data:
task_data:
ifname: fe-0/0/2
ipsuffix: 111
cisco-test:
hostname: cisco-test
groups:
- cisco
data:
task_data:
ifname: GigabitEthernet0/1/1
ipsuffix: 222
asn: 65111
α αΎααααααΊααΆ group.yamlα
---
cisco:
platform: ios
username: admin1
password: cisco1
juniper:
platform: junos
username: admin2
password: juniper2
αααααΆα’αααΈαααααΆαααΎαα‘αΎα ααΆαααΎααααα αααααΆαααα·α αα ααΆαααααααΎαα ααα‘α»ααααα αΆααααααΎα αααΆαααΆααααααααΈα―αααΆαααΆαααΎαααααααααΌαααΆαααααΌαααααα ααΉαααααΌααααα» ααΆαα»ααΆαααΎααααα.
ααΆαααααα spoiler ααΊααΆααααΆααααΆααα InventoryElement model
print(json.dumps(InventoryElement.schema(), indent=4))
{
"title": "InventoryElement",
"type": "object",
"properties": {
"hostname": {
"title": "Hostname",
"type": "string"
},
"port": {
"title": "Port",
"type": "integer"
},
"username": {
"title": "Username",
"type": "string"
},
"password": {
"title": "Password",
"type": "string"
},
"platform": {
"title": "Platform",
"type": "string"
},
"groups": {
"title": "Groups",
"default": [],
"type": "array",
"items": {
"type": "string"
}
},
"data": {
"title": "Data",
"default": {},
"type": "object"
},
"connection_options": {
"title": "Connection_Options",
"default": {},
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/ConnectionOptions"
}
}
},
"definitions": {
"ConnectionOptions": {
"title": "ConnectionOptions",
"type": "object",
"properties": {
"hostname": {
"title": "Hostname",
"type": "string"
},
"port": {
"title": "Port",
"type": "integer"
},
"username": {
"title": "Username",
"type": "string"
},
"password": {
"title": "Password",
"type": "string"
},
"platform": {
"title": "Platform",
"type": "string"
},
"extras": {
"title": "Extras",
"type": "object"
}
}
}
}
}
αααΌααααααα’αΆα ααΎααα ααΆαααΆαααΆααα ααααααααα·α ααΆαα·ααααα αααααααΌαα αααα»ααααααααααΎααααΈαααααααΆαααΆ, ααααα’αααααααααα αααα»α α’αΆαααΈαα»α.
$ ipython3
Python 3.6.9 (default, Nov 7 2019, 10:44:02)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.1.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from nornir import InitNornir
In [2]: nr = InitNornir(config_file="config.yaml", dry_run=True)
In [3]: nr.inventory.hosts
Out[3]:
{'srx-test': Host: srx-test, 'cisco-test': Host: cisco-test}
In [4]: nr.inventory.hosts['srx-test'].data
Out[4]: {'task_data': {'ifname': 'fe-0/0/2', 'ipsuffix': 111}}
In [5]: nr.inventory.hosts['srx-test']['task_data']
Out[5]: {'ifname': 'fe-0/0/2', 'ipsuffix': 111}
In [6]: nr.inventory.hosts['srx-test'].platform
Out[6]: 'junos'
α αΎαα
α»αααααα ααΌααααααα
ααααααΈααααα½αα―αα αααα»αβαα·αβααΆαβα’αααΈβαααβααααΌαβααΆαβααααααΆαβαα·αααβαα
βααΈβαααβααα αααα»αααααΆααααααα§ααΆα ααααααααααααα½α
ααΆααααα
ααΈ
from nornir import InitNornir
from nornir.plugins.tasks import networking, text
from nornir.plugins.functions.text import print_title, print_result
def config_and_deploy(task):
# Transform inventory data to configuration via a template file
r = task.run(task=text.template_file,
name="Base Configuration",
template="base.j2",
path=f"templates/{task.host.platform}")
# Save the compiled configuration into a host variable
task.host["config"] = r.result
# Save the compiled configuration into a file
with open(f"configs/{task.host.hostname}", "w") as f:
f.write(r.result)
# Deploy that configuration to the device using NAPALM
task.run(task=networking.napalm_configure,
name="Loading Configuration on the device",
replace=False,
configuration=task.host["config"])
nr = InitNornir(config_file="config.yaml", dry_run=True) # set dry_run=False, cross your fingers and run again
# run tasks
result = nr.run(task=config_and_deploy)
print_result(result)
ααα
α·ααααα»αααΆααααΎαααΆαααΆαααααα dry_run=αα·α αα
αααα»αααΆαα
αΆααααααΎαααααα»αααααΆαα nr.
αα
ααΈαααααΌα
ααααΆααΉααα
αααα»α ansible ααααΎαααΆαααΆαααααααααΌαααΆαα’αα»αααααααααΆααααααΆαααα
αααααααααααΌαααΆαααααΎα‘αΎα ααΆαααααααα
ααΆαααααααααααααΆαααααααααααΈααααΌαααΆααααα
α ααααααααΆααααααααΌαααΆααααααΆαααααα§ααααα (ααα»αααααα·αααααΆαααα ααΆα’αΆαααααααΎααΆαααΆααααα§ααααα αα·αααΆαα’αα»αααααααααα·ααΈαααααΆαα
αααα»α NAPALM) ααα»ααααααΆαααααααα
ααΆααααααααααααΈαα·αααααΌαααΆαα’αα»αααααααααααΆααααα αααααΆααααΆαααααΎααααΆααααααα»ααα α’αααααααΌααααααααΆαααΆααααααα
αα dry_run α¬ααααΌααααααααααααΆαα
ααΆ αα·ααα·α.
αα ααααααααααααΈαααααΌαααΆαααααα·ααααα· Nornir αααα αααααααα ααα»αααα’α·ααα ααΆαααα»αααΌαα
ααΆαααααα spoiler ααΊααΆααααααααααααΎαααΆαααααα»ααααα ααΎ Router ααΆαααααααΈαα
config_and_deploy***************************************************************
* cisco-test ** changed : True *******************************************
vvvv config_and_deploy ** changed : True vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv INFO
---- Base Configuration ** changed : True ------------------------------------- INFO
class-map match-all VIDEO_SURV
match access-group 111
policy-map VIDEO_SURV
class VIDEO_SURV
police 1500000 conform-action transmit exceed-action drop
interface GigabitEthernet0/1/1
description VIDEOSURV
ip address 10.10.222.254 255.255.255.0
service-policy input VIDEO_SURV
router bgp 65001
network 10.10.222.0 mask 255.255.255.0
access-list 11 permit 10.10.222.0 0.0.0.255
access-list 111 permit ip 10.10.222.0 0.0.0.255 any
---- Loading Configuration on the device ** changed : True --------------------- INFO
+class-map match-all VIDEO_SURV
+ match access-group 111
+policy-map VIDEO_SURV
+ class VIDEO_SURV
+interface GigabitEthernet0/1/1
+ description VIDEOSURV
+ ip address 10.10.222.254 255.255.255.0
+ service-policy input VIDEO_SURV
+router bgp 65001
+ network 10.10.222.0 mask 255.255.255.0
+access-list 11 permit 10.10.222.0 0.0.0.255
+access-list 111 permit ip 10.10.222.0 0.0.0.255 any
^^^^ END config_and_deploy ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* srx-test ** changed : True *******************************************
vvvv config_and_deploy ** changed : True vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv INFO
---- Base Configuration ** changed : True ------------------------------------- INFO
set interfaces fe-0/0/2 unit 0 description "Video surveillance"
set interfaces fe-0/0/2 unit 0 family inet filter input limit-in
set interfaces fe-0/0/2 unit 0 family inet address 10.10.111.254/24
set policy-options policy-statement export2bgp term 1 from route-filter 10.10.111.0/24 exact
set security zones security-zone WAN interfaces fe-0/0/2
set firewall policer policer-1m if-exceeding bandwidth-limit 1m
set firewall policer policer-1m if-exceeding burst-size-limit 187k
set firewall policer policer-1m then discard
set firewall policer policer-1.5m if-exceeding bandwidth-limit 1500000
set firewall policer policer-1.5m if-exceeding burst-size-limit 280k
set firewall policer policer-1.5m then discard
set firewall filter limit-in term 1 then policer policer-1.5m
set firewall filter limit-in term 1 then count limiter
---- Loading Configuration on the device ** changed : True --------------------- INFO
[edit interfaces]
+ fe-0/0/2 {
+ unit 0 {
+ description "Video surveillance";
+ family inet {
+ filter {
+ input limit-in;
+ }
+ address 10.10.111.254/24;
+ }
+ }
+ }
[edit]
+ policy-options {
+ policy-statement export2bgp {
+ term 1 {
+ from {
+ route-filter 10.10.111.0/24 exact;
+ }
+ }
+ }
+ }
[edit security zones]
security-zone test-vpn { ... }
+ security-zone WAN {
+ interfaces {
+ fe-0/0/2.0;
+ }
+ }
[edit]
+ firewall {
+ policer policer-1m {
+ if-exceeding {
+ bandwidth-limit 1m;
+ burst-size-limit 187k;
+ }
+ then discard;
+ }
+ policer policer-1.5m {
+ if-exceeding {
+ bandwidth-limit 1500000;
+ burst-size-limit 280k;
+ }
+ then discard;
+ }
+ filter limit-in {
+ term 1 {
+ then {
+ policer policer-1.5m;
+ count limiter;
+ }
+ }
+ }
+ }
^^^^ END config_and_deploy ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ααΆααααΆααααααααΆαααα αααα»α ansible_vault
αα ααΎαα’ααααα αααα»αααΆαααααααΆααααααα·α ansibleααα»ααααααΆαα·ααααα’αΆαααααααΆααα’αααααααα αααα»ααα·αααΆα αΌαα α·ααααα½αααα αα»ααα ααΌα ααΆ αααααααΌαααΆααα ααΆα‘αΎαααΎααααΈααΆααααααααΆααααΎαα ααααΈααΆαααΎαααΎαα α αΎααααα ααααΆααΆαααα»αααααΆα αααΎαααΆαααααααααΆααααΎαααΆ ααΎαααΆαααΆααααΆαα αΌα/ααΆααααααααΆαααααααΆαααααααααααααα»αααααΆααα’αααααααΆααααααΊαα αααα»αααααααααΎαα αα αα αααα»αα―αααΆααα½αα gorups.yaml. αα·αααΆααααΆαα·αααα’αΆαααα αααααΆαααΆααα·αααααααααααΆαα½α αα»ααα.
αααααααααααΆαααΆααααααααΈ groups.yaml αα creds.yaml α αΎαα’αα·αααααΈαααΆααΆαα½α AES256 ααΆαα½αααΉαααΆααααααααΆαα 20 αααααα
$ cd inventory
$ cat creds.yaml
---
cisco:
username: admin1
password: cisco1
juniper:
username: admin2
password: juniper2
$ pwgen 20 -N 1 > vault.passwd
ansible-vault encrypt creds.yaml --vault-password-file vault.passwd
Encryption successful
$ cat creds.yaml
$ANSIBLE_VAULT;1.1;AES256
39656463353437333337356361633737383464383231366233386636333965306662323534626131
3964396534396333363939373539393662623164373539620a346565373439646436356438653965
39643266333639356564663961303535353364383163633232366138643132313530346661316533
6236306435613132610a656163653065633866626639613537326233653765353661613337393839
62376662303061353963383330323164633162386336643832376263343634356230613562643533
30363436343465306638653932366166306562393061323636636163373164613630643965636361
34343936323066393763323633336366366566393236613737326530346234393735306261363239
35663430623934323632616161636330353134393435396632663530373932383532316161353963
31393434653165613432326636616636383665316465623036376631313162646435
ααΆααΆααααααΆααα ααΆαα
αααααΎααααΈααααααααααααΎαα ααα·ααα-script ααΎααααΈααΆααα αα·αα’αα»αααααα·αααααααααα
ααΎααααΈααααΎααΌα
ααααα
αααα»αααααααΈαααααααΎααααααΆααααΈαααααΆααα
αΆααααααΎα nr = InitNornir(config_file=β¦ ααααααααΌαααΆααααααα
...
nr = InitNornir(config_file="config.yaml", dry_run=True) # set dry_run=False, cross your fingers and run again
# enrich Inventory with the encrypted vault data
from ansible_vault import Vault
vault_password_file="inventory/vault.passwd"
vault_file="inventory/creds.yaml"
with open(vault_password_file, "r") as fp:
password = fp.readline().strip()
vault = Vault(password)
vaultdata = vault.load(open(vault_file).read())
for a in nr.inventory.hosts.keys():
item = nr.inventory.hosts[a]
item.username = vaultdata[item.groups[0]]['username']
item.password = vaultdata[item.groups[0]]['password']
#print("hostname={}, username={}, password={}n".format(item.hostname, item.username, item.password))
# run tasks
...
ααΆααΆααα·αααΆαα vault.passwd αα·ααα½αααΆαααΈααΆαααα ααΆαα creds.yaml ααΌα αααα»αα§ααΆα ααααααααααα»αααα ααα»ααααααΆαα·αα’αΈαααααααΆααααΆααααα
αααα αΎαααΆααΆααα’αααααααΆααααααααα ααΆαα’αααααααΈαααΈαααα’αααΈ Cisco + Zabbix ααΉαααααα ααα»ααααααααα·ααααααΆααααα·α α’αααΈααααααααααααα·ααααααα α αΎαααΆαααααΆααα»αααα αααα»αααΆααααααααααααα’αααΈ RESTCONF αα αααα»α Ciscoα
ααααα: www.habr.com