рдСрдЯреЛ рдЙрддреНрдкрдиреНрди рдФрд░ рднрд░реЗрдВ рдиреЗрдЯрд╡рд░реНрдХ рдбрд┐рд╡рд╛рдЗрд╕ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рддрддреНрд╡ Nornir рдХреЗ рд╕рд╛рде


рдирдорд╕реНрдХрд╛рд░, рд╣реЗрдмреНрд░!


рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдорд┐рдХрд░реЛрдЯрд┐рдХ рдФрд░ рд▓рд┐рдирдХреНрд╕ рдХрд╛ рдПрдХ рд▓реЗрдЦ рдпрд╣рд╛рдВ рдлрд┐рд╕рд▓ рдЧрдпрд╛ ред рд░реВрдЯреАрди рдФрд░ рд╕реНрд╡рдЪрд╛рд▓рди рдЬрд╣рд╛рдВ рдЬреАрд╡рд╛рд╢реНрдо рд╕рд╛рдзрдиреЛрдВ рджреНрд╡рд╛рд░рд╛ рдПрдХ рд╕рдорд╛рди рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рдХреА рдЧрдИ рдереАред рдФрд░ рдпрджреНрдпрдкрд┐ рдпрд╣ рдХрд╛рд░реНрдп рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣рдмреНрд░реЗ рдкрд░ рдХреБрдЫ рднреА рд╕рдорд╛рди рдирд╣реАрдВ рд╣реИред рдореИрдВ рдЕрдкрдиреА рдмрд╛рдЗрдХ рдХреЛ рдкреНрд░рддрд┐рд╖реНрдард┐рдд рдЖрдИрдЯреА рд╕рдореБрджрд╛рдп рдХреЛ рдкреЗрд╢ рдХрд░рдиреЗ рдХреА рд╣рд┐рдореНрдордд рдХрд░рддрд╛ рд╣реВрдВред


рдпрд╣ рдЗрд╕ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реА рдмрд╛рдЗрдХ рдирд╣реАрдВ рд╣реИред рдкрд╣рд▓рд╛ рд╡рд┐рдХрд▓реНрдк рдХрдИ рд╕рд╛рд▓ рдкрд╣рд▓реЗ 1sx рд╕рдВрд╕реНрдХрд░рдг рдкрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред x.x. рд╕рд╛рдЗрдХрд┐рд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╢рд╛рдпрдж рд╣реА рдХрднреА рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдЗрд╕рд▓рд┐рдП рд▓рдЧрд╛рддрд╛рд░ рдЬрдВрдЧ рд▓рдЧрд╛ рд╣реБрдЖ рдерд╛ред рдЗрд╕ рдЕрд░реНрде рдореЗрдВ рдХрд┐ рдХрд╛рд░реНрдп рд╕реНрд╡рдпрдВ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рдЬрд┐рддрдиреА рдмрд╛рд░ рдЕрджреНрдпрддрд┐рдд рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд╣реЛрддрд╛ рд╣реИред рдФрд░ рд╣рд░ рдмрд╛рд░ рдЬрдм рдЖрдкрдХреЛ рдЬрд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реЛрддреА рд╣реИ, рддреЛ рдЪреЗрди рдЧрд┐рд░ рдЬрд╛рдПрдЧреА, рдкрд╣рд┐рдпрд╛ рдЧрд┐рд░ рдЬрд╛рдПрдЧрд╛ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдкрд╣рд▓рд╛ рднрд╛рдЧ, рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреА рдкреАрдврд╝реА - рд╣рдореЗрд╢рд╛ рдмрд╣реБрдд рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░рддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрдВрдЬрди рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ jinja2 рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ред рд▓реЗрдХрд┐рди рджреВрд╕рд░рд╛ рднрд╛рдЧ - рд░реЛрд▓рд┐рдВрдЧ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рддрд╛ рд╣реИ, рдПрдХ рдирд┐рдпрдо рдХреЗ рд░реВрдк рдореЗрдВ рдЖрд╢реНрдЪрд░реНрдп рд╣реБрдЖред рдФрд░ рдЪреВрдВрдХрд┐ рдореБрдЭреЗ рд╕реИрдХрдбрд╝реЛрдВ рдбрд┐рд╡рд╛рдЗрд╕реЛрдВ рдХреЗ рдлрд░реНрд╢ рдХреЛ рджреВрд░рд╕реНрде рд░реВрдк рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рд╣реИ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдХреБрдЫ рд╣рдЬрд╛рд░реЛрдВ рдХрд┐рд▓реЛрдореАрдЯрд░ рджреВрд░ рд╣реИрдВ, рдЗрд╕ рдЙрдкрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдереЛрдбрд╝рд╛ рдХрд╖реНрдЯрдкреНрд░рдж рдерд╛ред


рдпрд╣рд╛рдБ рдореБрдЭреЗ рдпрд╣ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдореЗрд░реА рдЕрд╕реБрд░рдХреНрд╖рд╛, рдЕрдкрдиреА рдХрдорд┐рдпреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдореЗрд░реЗ рд╕рд╛рде рдкрд░рд┐рдЪрд┐рдд рд╣реЛрдиреЗ рдХреА рдХрдореА рдореЗрдВ рд╣реИред рдФрд░ рдпрд╣, рд╡реИрд╕реЗ, рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБ рд╣реИред ansible рдПрдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рд╣реИ, рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ DSL (рдбреЛрдореЗрди рд╡рд┐рд╢рд┐рд╖реНрдЯ рднрд╛рд╖рд╛) рдХреЗ рд╕рд╛рде рдЬреНрдЮрд╛рди рдХрд╛ рдПрдХ рдбреЛрдореЗрди рд╣реИ, рдЬрд┐рд╕реЗ рдПрдХ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд╕реНрддрд░ рдкрд░ рдмрдирд╛рдП рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЦреИрд░, рд╡рд╣ рдХреНрд╖рдг рдЬреЛ рдмрд╣реБрдд рдЬрд▓реНрджреА рд╡рд┐рдХрд╕рд┐рдд рд╣реЛ рд░рд╣рд╛ рд╣реИ, рдФрд░ рдкрд┐рдЫрдбрд╝реЗ рдЕрдиреБрдХреВрд▓рддрд╛ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖ рд╕рдВрдмрдВрдз рдХреЗ рдмрд┐рдирд╛, рдЖрддреНрдорд╡рд┐рд╢реНрд╡рд╛рд╕ рдирд╣реАрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реИред


рдЗрд╕рд▓рд┐рдП, рдмрд╣реБрдд рдкрд╣рд▓реЗ рдирд╣реАрдВ, рд╕рд╛рдЗрдХрд┐рд▓ рдХрд╛ рджреВрд╕рд░рд╛ рд╕рдВрд╕реНрдХрд░рдг рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЕрдЬрдЧрд░ рдореЗрдВ рдЗрд╕ рдмрд╛рд░, рдпрд╛ рдмрд▓реНрдХрд┐, рдЕрдЬрдЧрд░ рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рдПрдХ рдврд╛рдВрдЪреЗ рдореЗрдВ рдФрд░ рдЕрдЬрдЧрд░ рдХреЗ рд▓рд┐рдП рдЬрд┐рд╕реЗ рдиреЛрд░рд┐рди рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ


рддреЛ - рдиреЛрд░реНрдирд┐рдпрд░ рдПрдХ рдорд╛рдЗрдХреНрд░реЛрдлреНрд░рд╛рдорд╡рд░реНрдХ рд╣реИ рдЬрд┐рд╕реЗ рдЕрдЬрдЧрд░ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЕрдЬрдЧрд░ рдХреЗ рд▓рд┐рдП рдФрд░ рд╕реНрд╡рдЪрд╛рд▓рди рдХреЗ рд▓рд┐рдП рдЗрд░рд╛рджрд╛ рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЗ рд▓рд┐рдП, рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рд╕рдХреНрд╖рдо рдбреЗрдЯрд╛ рддреИрдпрд╛рд░ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдЕрд░реНрдерд╛рддреНред рдореЗрдЬрдмрд╛рдиреЛрдВ рдФрд░ рдЙрдирдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рд╕реВрдЪреА, рд▓реЗрдХрд┐рди рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдПрдХ рдЕрд▓рдЧ рдбреАрдПрд╕рдПрд▓ рдкрд░ рдирд╣реАрдВ рд▓рд┐рдЦреА рдЬрд╛рддреА рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕рднреА рдмрд╣реБрдд рдкреБрд░рд╛рдиреА рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдмрд╣реБрдд рдЕрдЪреНрдЫреА рдЯреЛрди [рдФрд░ | рдЖрд╣] рдЯреЛрди рдкрд░ред


рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдпрд╣ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЬреАрд╡рд┐рдд рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рдХреНрдпрд╛ рд╣реИред


рдореЗрд░рд╛ рджреЗрд╢ рднрд░ рдореЗрдВ рдХрдИ рджрд░реНрдЬрди рдХрд╛рд░реНрдпрд╛рд▓рдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╢рд╛рдЦрд╛ рдиреЗрдЯрд╡рд░реНрдХ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдпрд╛рд▓рдп рдореЗрдВ, рдПрдХ WAN рд░рд╛рдЙрдЯрд░ рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рд╡рд┐рднрд┐рдиреНрди рдСрдкрд░реЗрдЯрд░реЛрдВ рд╕реЗ рдХрдИ рд╕рдВрдЪрд╛рд░ рдЪреИрдирд▓реЛрдВ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред рд░реВрдЯрд┐рдВрдЧ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдмреАрдЬреАрдкреА рд╣реИред WAN рд░рд╛рдЙрдЯрд░ рджреЛ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реЛрддреЗ рд╣реИрдВ: рд╕рд┐рд╕реНрдХреЛ ISG рдпрд╛ рдЬреБрдирд┐рдкрд░ SRXред


рдЕрдм рдХрд╛рд░реНрдп: рд╢рд╛рдЦрд╛ рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рд╕рднреА рд╡рд╛рди рд░рд╛рдЙрдЯрд░ рдкрд░ рдПрдХ рдЕрд▓рдЧ рдкреЛрд░реНрдЯ рдореЗрдВ рд╡реАрдбрд┐рдпреЛ рдирд┐рдЧрд░рд╛рдиреА рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд░реНрдкрд┐рдд рд╕рдмрдиреЗрдЯ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ - рдмреАрдЬреАрдкреА рдореЗрдВ рдЗрд╕ рд╕рдмрдиреЗрдЯ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░реЗрдВ - рд╕рдорд░реНрдкрд┐рдд рдмрдВрджрд░рдЧрд╛рд╣ рдХреЗ рд▓рд┐рдП рдЧрддрд┐ рд╕реАрдорд╛ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВред


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдХреБрдЫ рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рддреИрдпрд╛рд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕рд┐рд╕реНрдХреЛ рдФрд░ рдЬреБрдирд┐рдкрд░ рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рддреИрдпрд╛рд░ рдХрд┐рдП рдЬрд╛рдПрдВрдЧреЗред рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдмрд┐рдВрджреБ рдФрд░ рдХрдиреЗрдХреНрд╢рди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рддреИрдпрд╛рд░ рдХрд░рдирд╛ рднреА рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдЕрд░реНрдерд╛рддреНред рдЙрд╕ рд╕реВрдЪреА рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП


рд╕рд┐рд╕реНрдХреЛ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдЯреЗрдореНрдкрд▓реЗрдЯ:


$ 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 

рдЬреБрдирд┐рдкрд░ рдХреЗ рд▓рд┐рдП рдЯреЗрдореНрдкреНрд▓реЗрдЯ:


 $ 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 

рдмреЗрд╢рдХ, рдЫрдд рд╕реЗ рдирд╣реАрдВ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдХрд╛рд░реНрдп рд╡рд┐рдиреНрдпрд╛рд╕ рдХреЗ рдмреАрдЪ рдХрд╛ рдЕрдВрддрд░ рдерд╛-рдпрд╣ рд╡рд┐рднрд┐рдиреНрди рдореЙрдбрд▓реЛрдВ рдХреЗ рджреЛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд░рд╛рдЙрдЯрд░реЛрдВ рдкрд░ рдХрд╛рд░реНрдп рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдмрди рдЧрдпрд╛ред


рд╣рдорд╛рд░реЗ рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рд╕реЗ, рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЬреБрдирд┐рдкрд░ рдХреЗ рд▓рд┐рдП рджреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдФрд░ рд╕рд┐рд╕реНрдХреЛ рдХреЗ рд▓рд┐рдП 3 рдкреИрд░рд╛рдореАрдЯрд░ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИрдВред рдпрд╣рд╛рдБ рд╡реЗ рд╣реИрдВ:


  • ifname
  • ipsuffix
  • ASN

рдЕрдм рд╣рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдбрд┐рд╡рд╛рдЗрд╕ рдХреЗ рд▓рд┐рдП рдЗрди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рддреНред рд╡рд╣реА рдЗрдиреНрд╡реЗрдВрдЯреНрд░реА рдХрд░реЛ ред


рдЗрдиреНрд╡реЗрдВрдЯреНрд░реА рдХреЗ рд▓рд┐рдП рд╣рдо рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЗрдирд┐рд╢рд┐рдпрд▓рд┐рдВрдЧ рдиреЙрд░реНрдирд┐рд░ рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░реЗрдВрдЧреЗ


рдпрд╛рдиреА рдПрдХ рд╣реА рдлрд╝рд╛рдЗрд▓ рдХрдВрдХрд╛рд▓ рдмрдирд╛рдПрдБ:


 . тФЬтФАтФА config.yaml тФЬтФАтФА inventory тФВ тФЬтФАтФА defaults.yaml тФВ тФЬтФАтФА groups.yaml тФВ тФФтФАтФА hosts.yaml 

Config.yaml рдлрд╝рд╛рдЗрд▓ - рдорд╛рдирдХ nornir рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓


 $ 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 рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдореБрдЦреНрдп рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВрдЧреЗ, group.yaml рдореЗрдВ рд╕рдореВрд╣ (рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдпреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо / рдкрд╛рд╕рд╡рд░реНрдб рд╣реИрдВ), рдФрд░ рд╣рдо рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдореЗрдВ рдХреБрдЫ рднреА рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рддреАрди рдорд┐рдирдЯ рджрд░реНрдЬ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдпрд╣ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ yaml рдлрд╝рд╛рдЗрд▓ рд╣реИ рдЕрд▓рдмрддреНрддрд╛ рдЦрд╛рд▓реАред


рдпрд╣ рд╡рд╣реА рд╣реИ рдЬреЛ 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 

рдФрд░ рдпрд╣рд╛рдБ рд╕рдореВрд╣ рд╣реИред


 --- cisco: platform: ios username: admin1 password: cisco1 juniper: platform: junos username: admin2 password: juniper2 

рдпрд╣рд╛рдБ рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рд╕реВрдЪреА рд╣реИ ред рдЖрд░рдВрднреАрдХрд░рдг рдХреЗ рджреМрд░рд╛рди, рдЗрдиреНрд╡реЗрдВрдЯреНрд░реА рдлрд╝рд╛рдЗрд▓реЛрдВ рд╕реЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдЗрдиреНрд╡реЗрдВрдЯрд░реАрдореЗрдВрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдореИрдк рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


рд╕реНрдкреЙрдЗрд▓рд░ рдХреЗ рддрд╣рдд, рдЗрдиреНрд╡реЗрдВрдЯрд░реАрдИрдореЗрдВрдЯ рдореЙрдбрд▓ рдЖрд░реЗрдЦ
 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" } } } } } 

рдпрд╣ рдореЙрдбрд▓ рдереЛрдбрд╝рд╛ рднреНрд░рд╛рдордХ рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ, рдЦрд╛рд╕рдХрд░ рдкрд╣рд▓реЗред IPython рдореЗрдВ рдЗрдВрдЯрд░рдПрдХреНрдЯрд┐рд╡ рдореЛрдб рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдореЗрдВ рдмрд╣реБрдд рдорджрдж рдХрд░рддрд╛ рд╣реИред


  $ 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) 

Nr рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рд▓рд╛рдЗрди рдореЗрдВ dry_run = True рдкреИрд░рд╛рдореАрдЯрд░ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВред
рдпрд╣рд╛рдВ, рдЬреИрд╕рд╛ рдХрд┐ рдПрдХ рд╡реНрдпрд╡рд╣рд╛рд░реНрдп рдореЗрдВ , рдПрдХ рдкрд░реАрдХреНрд╖рдг рд░рди рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд░рд╛рдЙрдЯрд░ рд╕реЗ рдХрдиреЗрдХреНрд╢рди рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдПрдХ рдирдпрд╛ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рддрдм рдбрд┐рд╡рд╛рдЗрд╕ рджреНрд╡рд╛рд░рд╛ рдорд╛рдиреНрдп рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдЯреАрдХ рдирд╣реАрдВ рд╣реИ; рдпрд╣ рдбрд┐рд╡рд╛рдЗрд╕ рдХреЗ рд╕рдорд░реНрдерди рдФрд░ NAPALM рдореЗрдВ рдбреНрд░рд╛рдЗрд╡рд░ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ), рд▓реЗрдХрд┐рди рдирдпрд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕реАрдзреЗ рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ ред рдпреБрджреНрдз рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ dry_run рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рд╣рдЯрд╛рдирд╛ рд╣реЛрдЧрд╛ рдпрд╛ рдЗрд╕рдХреЗ рдореВрд▓реНрдп рдХреЛ рдЧрд▓рдд рдореЗрдВ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ред


рдЬрдм рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЪрд▓рддреА рд╣реИ, рддреЛ рдиреЙрд░реНрдирд┐рд░ рдХрдВрд╕реЛрд▓ рдореЗрдВ рд╡рд┐рд╕реНрддреГрдд рд▓реЙрдЧ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред


рд╕реНрдкреЙрдЗрд▓рд░ рдХреЗ рддрд╣рдд, рджреЛ рдкрд░реАрдХреНрд╖рдг рд░рд╛рдЙрдЯрд░ рдкрд░ рдЪрд▓рд╛рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдореБрдХрд╛рдмрд▓реЗ рдХрд╛ рдирд┐рд╖реНрдХрд░реНрд╖:
 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 рдореЗрдВ рдЫрд┐рдкрд╛рдПрдВ


рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ, рдореИрдВ рдереЛрдбрд╝рд╛ рд╕рд╛ рднрд╛рдЧ рдЧрдпрд╛, рд▓реЗрдХрд┐рди рд╡рд╣рд╛рдВ рд╕рдм рдХреБрдЫ рдЗрддрдирд╛ рдмреБрд░рд╛ рдирд╣реАрдВ рдерд╛ред рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдирдХреА рддрд┐рдЬреЛрд░реА рдкрд╕рдВрдж рд╣реИ, рдЬрд┐рд╕реЗ рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рджреГрд╖реНрдЯрд┐ рд╕реЗ рдЫрд┐рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдФрд░ рд╢рд╛рдпрдж рдмрд╣реБрддреЛрдВ рдиреЗ рджреЗрдЦрд╛ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо / рдкрд╛рд╕рд╡рд░реНрдб рд╣реИрдВ рдЬреЛ рд╕рднреА рд▓рдбрд╝рд╛рдИ рд░рд╛рдЙрдЯрд░реНрд╕ рдХреЗ рд▓рд┐рдП рдЦреБрд▓реЗ рд╣реИрдВред рдпрд╣ рдмрджрд╕реВрд░рдд рд╣реИ, рдЬрд╝рд╛рд╣рд┐рд░ рд╣реИред рдЖрдЗрдП рдЗрд╕ рдбреЗрдЯрд╛ рдХреЛ рддрд┐рдЬреЛрд░реА рд╕реЗ рд╕реБрд░рдХреНрд╖рд┐рдд рдХрд░реЗрдВред


рд╣рдо group.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 

рдЗрддрдирд╛ рд╕рд░рд▓ред рдЗрд╕ рдбреЗрдЯрд╛ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ рдЙрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рд╣рдорд╛рд░реА Nornir рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдкрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИред
рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ, рдЖрд░рдВрднреАрдХрд░рдг рд░реЗрдЦрд╛ рдХреЗ рдмрд╛рдж 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 рдореЗрд░реЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдХреНрд░реЗрдбреЗрдВрд╢рд┐рдпрд▓ рдХреЗ рдмрдЧрд▓ рдореЗрдВ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рд▓реЗрдХрд┐рди рдЦреЗрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред


рдЕрднреА рдХреЗ рд▓рд┐рдП рдмрд╕ рдЗрддрдирд╛ рд╣реАред рд╕рд┐рд╕реНрдХреЛ + рдЬрд╝реИрдмрд┐рдХреНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рд▓реЗрдЦ рдЖ рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рд╕реНрд╡рдЪрд╛рд▓рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рд╕рд╛ рдирд╣реАрдВ рд╣реИред рдФрд░ рдирд┐рдХрдЯ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдореИрдВ рд╕рд┐рд╕реНрдХреЛ рдореЗрдВ RESTCONF рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛ рд░рд╣рд╛ рд╣реВрдВред

Source: https://habr.com/ru/post/hi482194/


All Articles