เบเบฒเบ™เบœเบฐเบฅเบดเบ”เบญเบฑเบ”เบ•เบฐเป‚เบ™เบกเบฑเบ”เปเบฅเบฐเบเบฒเบ™เบ•เบทเปˆเบกเบ‚เปเป‰เบกเบนเบ™เปƒเบชเปˆเบญเบปเบ‡เบ›เบฐเบเบญเบšเบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบญเบธเบ›เบฐเบเบญเบ™เป€เบ„เบทเบญเบ‚เปˆเบฒเบเป‚เบ”เบเปƒเบŠเป‰ Nornir

เบเบฒเบ™เบœเบฐเบฅเบดเบ”เบญเบฑเบ”เบ•เบฐเป‚เบ™เบกเบฑเบ”เปเบฅเบฐเบเบฒเบ™เบ•เบทเปˆเบกเบ‚เปเป‰เบกเบนเบ™เปƒเบชเปˆเบญเบปเบ‡เบ›เบฐเบเบญเบšเบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบญเบธเบ›เบฐเบเบญเบ™เป€เบ„เบทเบญเบ‚เปˆเบฒเบเป‚เบ”เบเปƒเบŠเป‰ Nornir

Hey Habr!

เบšเปเปˆเบ”เบปเบ™เบกเบฒเบ™เบตเป‰, เบšเบปเบ”เบ„เบงเบฒเบกเป„เบ”เป‰เบ›เบฒเบเบปเบ”เบขเบนเปˆเบ™เบตเป‰ Mikrotik เปเบฅเบฐ Linux. เบ›เบปเบเบเบฐเบ•เบดเปเบฅเบฐเบญเบฑเบ”เบ•เบฐเป‚เบ™เบกเบฑเบ” เบšเปˆเบญเบ™เบ—เบตเปˆเบšเบฑเบ™เบซเบฒเบ—เบตเปˆเบ„เป‰เบฒเบเบ„เบทเบเบฑเบ™เป„เบ”เป‰เบ–เบทเบเปเบเป‰เป„เบ‚เป‚เบ”เบเปƒเบŠเป‰เบงเบดเบ—เบตเบเบฒเบ™เบŸเบญเบ”เบŠเบดเบงเบ—เปเบฒ. เปเบฅเบฐเป€เบ–เบดเบ‡เปเบกเปˆเบ™เบงเปˆเบฒเบงเบฝเบเบ‡เบฒเบ™เปเบกเปˆเบ™เบ›เบปเบเบเบฐเบ•เบดเบขเปˆเบฒเบ‡เบชเบปเบกเบšเบนเบ™, เบšเปเปˆเบกเบตเบซเบเบฑเบ‡เบ„เป‰เบฒเบเบ„เบทเบเบฑเบ™เบเปˆเบฝเบงเบเบฑเบšเบกเบฑเบ™เบขเบนเปˆเปƒเบ™Habre. เบ‚เป‰เบญเบเบเป‰เบฒเบชเบฐเป€เปœเบตเบฅเบปเบ”เบ–เบตเบšเบ‚เบญเบ‡เบ‚เป‰เบญเบเปƒเบซเป‰เบเบฑเบšเบŠเบธเบกเบŠเบปเบ™เป„เบญเบ—เบตเบ—เบตเปˆเป€เบ„เบปเบฒเบฅเบปเบš.

เบ™เบตเป‰เบšเปเปˆเปเบกเปˆเบ™เบฅเบปเบ”เบ–เบตเบšเบ—เปเบฒเบญเบดเบ”เบชเปเบฒเบฅเบฑเบšเบงเบฝเบเบ‡เบฒเบ™เบ”เบฑเปˆเบ‡เบเปˆเบฒเบง. เบ—เบฒเบ‡เป€เบฅเบทเบญเบเบ—เปเบฒเบญเบดเบ”เป„เบ”เป‰เบ–เบทเบเบ›เบฐเบ•เบดเบšเบฑเบ”เบซเบผเบฒเบเบ›เบตเบเปˆเบญเบ™เบซเบ™เป‰เบฒเบ™เบตเป‰เบเบฑเบšเบ„เบทเบ™เป„เบ›เบšเปˆเบญเบ™เปƒเบ™ เบ•เบญเบšเบฎเบฑเบšเป„เบ”เป‰ เบฅเบธเป‰เบ™ 1.x.x. เบฅเบปเบ”เบ–เบตเบšเบšเปเปˆเบ„เปˆเบญเบเป„เบ”เป‰เบ™เบณเปƒเบŠเป‰ เปเบฅเบฐเป€เบžเบฒเบฐเบชเบฐเบ™เบฑเป‰เบ™เบˆเบถเปˆเบ‡เป€เบเบตเบ” rusted เบขเบนเปˆเบชเบฐเป€เปเบต. เปƒเบ™เบ„เบงเบฒเบกเบฎเบนเป‰เบชเบถเบเบงเปˆเบฒเบงเบฝเบเบ‡เบฒเบ™เบ•เบปเบงเบกเบฑเบ™เป€เบญเบ‡เบšเปเปˆเป€เบเบตเบ”เบ‚เบทเป‰เบ™เป€เบฅเบทเป‰เบญเบเป†เป€เบ—เบปเปˆเบฒเบ—เบตเปˆเบชเบฐเบšเบฑเบšเบ›เบฑเบšเบ›เบธเบ‡ เบ•เบญเบšเบฎเบฑเบšเป„เบ”เป‰. เปเบฅเบฐเบ—เบธเบเบ„เบฑเป‰เบ‡เบ—เบตเปˆเป€เบˆเบปเป‰เบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เบ‚เบฑเบšเบฅเบปเบ”, เบฅเบฐเบšเบปเบšเบ•เปˆเบญเบ‡เป‚เบชเป‰เบ•เบปเบเบซเบผเบทเบฅเปเป‰เบซเบผเบธเบ”เบฅเบปเบ‡. เบขเปˆเบฒเบ‡เปƒเบ”เบเปเบ•เบฒเบก, เบžเบฒเบเบชเปˆเบงเบ™เบ—เปเบฒเบญเบดเบ”, เบเบฒเบ™เบชเป‰เบฒเบ‡ configs, เบชเบฐเป€เบซเบกเบตเป€เบฎเบฑเบ”เบงเบฝเบเบขเปˆเบฒเบ‡เบŠเบฑเบ”เป€เบˆเบ™เบซเบผเบฒเบ, เป‚เบŠเบเบ”เบต jinja2 เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบเป„เบ”เป‰เบ–เบทเบเบชเป‰เบฒเบ‡เบ•เบฑเป‰เบ‡เบ‚เบถเป‰เบ™เบ”เบปเบ™เบ™เบฒเบ™. เปเบ•เปˆเบžเบฒเบเบชเปˆเบงเบ™เบ—เบตเบชเบญเบ‡ - rolling out configs - เบ›เบปเบเบเบฐเบ•เบดเปเบฅเป‰เบงเป„เบ”เป‰เบ™เปเบฒเป€เบญเบปเบฒเบ„เบงเบฒเบกเปเบ›เบเปƒเบˆ. เปเบฅเบฐเบ™เบฑเบšเบ•เบฑเป‰เบ‡เปเบ•เปˆเบ‚เป‰เบญเบเบ•เป‰เบญเบ‡เบกเป‰เบงเบ™ config เบซเปˆเบฒเบ‡เป„เบเบชเบญเบเบซเบผเบตเบเป€เบ–เบดเบ‡เป€เบ„เบดเปˆเบ‡เบซเบ™เบถเปˆเบ‡เบฎเป‰เบญเบเบญเบธเบ›เบฐเบเบญเบ™, เบšเบฒเบ‡เบšเปˆเบญเบ™เบขเบนเปˆเป„เบเบซเบฅเบฒเบเบžเบฑเบ™เบเบดเป‚เบฅเปเบกเบฑเบ”, เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เป€เบ„เบทเปˆเบญเบ‡เบกเบทเบ™เบตเป‰เปเบกเปˆเบ™เบซเบ™เป‰เบฒเป€เบšเบทเปˆเบญเป€เบฅเบฑเบเบ™เป‰เบญเบ.

เปƒเบ™เบ—เบตเปˆเบ™เบตเป‰เบ‚เป‰เบญเบเบ•เป‰เบญเบ‡เบเบญเบกเบฎเบฑเบšเบงเปˆเบฒเบ„เบงเบฒเบกเบšเปเปˆเปเบ™เปˆเบ™เบญเบ™เบ‚เบญเบ‡เบ‚เป‰เบญเบเบกเบฑเบเบˆเบฐเบขเบนเปˆเปƒเบ™เบเบฒเบ™เบ‚เบฒเบ”เบ„เบงเบฒเบกเบ„เบธเป‰เบ™เป€เบ„เบตเบเบ‚เบญเบ‡เบ‚เป‰เบญเบ เบ•เบญเบšเบฎเบฑเบšเป„เบ”เป‰เบเปˆเบงเบฒเบขเบนเปˆเปƒเบ™เบ‚เปเป‰เบšเบปเบเบœเปˆเบญเบ‡เบ‚เบญเบ‡เบกเบฑเบ™. เปเบฅเบฐเบ™เบตเป‰, เป‚เบ”เบเบงเบดเบ—เบตเบ—เบฒเบ‡เบเบฒเบ™, เป€เบ›เบฑเบ™เบˆเบธเบ”เบชเปเบฒเบ„เบฑเบ™. เบ•เบญเบšเบฎเบฑเบšเป„เบ”เป‰ เปเบกเปˆเบ™เปเบเบเบ•เปˆเบฒเบ‡เบซเบฒเบเบขเปˆเบฒเบ‡เบชเบปเบกเบšเบนเบ™, เบžเบทเป‰เบ™เบ—เบตเปˆเบ„เบงเบฒเบกเบฎเบนเป‰เบ‚เบญเบ‡เบ•เบปเบ™เป€เบญเบ‡เบเบฑเบš DSL (เบžเบฒเบชเบฒเบชเบฐเป€เบžเบฒเบฐเบ‚เบญเบ‡เป‚เบ”เป€เบกเบ™), เป€เบŠเบดเปˆเบ‡เบ•เป‰เบญเบ‡เป„เบ”เป‰เบฎเบฑเบšเบเบฒเบ™เบฎเบฑเบเบชเบฒเป„เบงเป‰เปƒเบ™เบฅเบฐเบ”เบฑเบšเบ„เบงเบฒเบกเบซเบกเบฑเป‰เบ™เปƒเบˆ. เปเบฅเป‰เบง, เป€เบงเบฅเบฒเบ™เบฑเป‰เบ™ เบ•เบญเบšเบฎเบฑเบšเป„เบ”เป‰ เบกเบฑเบ™เบเปเบฒเบฅเบฑเบ‡เบžเบฑเบ”เบ—เบฐเบ™เบฒเบขเปˆเบฒเบ‡เป„เบงเบงเบฒ, เปเบฅเบฐเป‚เบ”เบเบšเปเปˆเบกเบตเบเบฒเบ™เบžเบดเบˆเบฒเบฅเบฐเบ™เบฒเบžเบดเป€เบชเบ”เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป€เบ‚เบปเป‰เบฒเบเบฑเบ™เป„เบ”เป‰เปƒเบ™เบ”เป‰เบฒเบ™เบซเบฅเบฑเบ‡, เบกเบฑเบ™เบšเปเปˆเป„เบ”เป‰เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบซเบกเบฑเป‰เบ™เปƒเบˆ.

เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบšเปเปˆเบ”เบปเบ™เบเปˆเบญเบ™เบซเบ™เป‰เบฒเบ™เบตเป‰, เบฅเบปเบ”เบ–เบตเบšเบฎเบธเปˆเบ™เบ—เบตเบชเบญเบ‡เป„เบ”เป‰เบ–เบทเบเบ›เบฐเบ•เบดเบšเบฑเบ”. เป€เบงเบฅเบฒเบ™เบตเป‰ python, เบซเบผเบทเปเบ—เบ™เบ—เบตเปˆเบˆเบฐเบขเบนเปˆเปƒเบ™เบเบญเบšเบ—เบตเปˆเบ‚เบฝเบ™เป„เบงเป‰เปƒเบ™ python เปเบฅเบฐ เบชเบณ เบฅเบฑเบš python เบžเบฒเบเปƒเบ•เป‰เบŠเบทเปˆ เบ™เปเป€เบ™เบต

เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™ - เบ™เปเป€เบ™เบต เป€เบ›เบฑเบ™ microframework เบฅเบฒเบเบฅเบฑเบเบญเบฑเบเบชเบญเบ™เปƒเบ™ python เปเบฅเบฐ เบชเบณ เบฅเบฑเบš python เปเบฅเบฐโ€‹เบ–เบทเบโ€‹เบญเบญเบโ€‹เปเบšเบšโ€‹เบชเปเบฒโ€‹เบฅเบฑเบšโ€‹เบเบฒเบ™โ€‹เบญเบฑเบ”โ€‹เบ•เบฐโ€‹เป‚เบ™โ€‹เบกเบฑเบ”โ€‹. เป€เบŠเบฑเปˆเบ™เบ”เบฝเบงเบเบฑเบ™เบเบฑเบšเบเปเบฅเบฐเบ™เบตเบ—เบตเปˆเบกเบต เบ•เบญเบšเบฎเบฑเบšเป„เบ”เป‰, เป€เบžเบทเปˆเบญเปเบเป‰เป„เบ‚เบšเบฑเบ™เบซเบฒเบขเบนเปˆเบ—เบตเปˆเบ™เบตเป‰, เบเบฒเบ™เบเบฐเบเบฝเบกเบ‚เปเป‰เบกเบนเบ™เบ—เบตเปˆเบกเบตเบ„เบงเบฒเบกเบชเบฒเบกเบฒเบ”เปƒเบ™เบเบฒเบ™, i.e. เบชเบดเบ™เบ„เป‰เบฒเบ„เบปเบ‡เบ„เบฑเบ‡เบ‚เบญเบ‡ hosts เปเบฅเบฐเบ•เบปเบงเบเปเบฒเบ™เบปเบ”เบเบฒเบ™เบ‚เบญเบ‡เป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒ, เปเบ•เปˆ scripts เบšเปเปˆเป„เบ”เป‰เบ‚เบฝเบ™เบขเบนเปˆเปƒเบ™ DSL เปเบเบเบ•เปˆเบฒเบ‡เบซเบฒเบ, เปเบ•เปˆเปƒเบ™เบ”เบฝเบงเบเบฑเบ™เบšเปเปˆเป€เบเบปเปˆเบฒเบซเบผเบฒเบ, เปเบ•เปˆเบ”เบตเบซเบผเบฒเบ p[i|i]ton.

เปƒเบซเป‰เป€เบšเบดเปˆเบ‡เบชเบดเปˆเบ‡เบ—เบตเปˆเบกเบฑเบ™เปƒเบŠเป‰เบ•เบปเบงเบขเปˆเบฒเบ‡เบชเบปเบ”เบ•เปเปˆเป„เบ›เบ™เบตเป‰.

เบ‚เป‰เบญเบเบกเบตเป€เบ„เบทเบญเบ‚เปˆเบฒเบเบชเบฒเบ‚เบฒเบ—เบตเปˆเบกเบตเบซเป‰เบญเบ‡เบเบฒเบ™เบซเบผเบฒเบเบชเบดเบšเปเบซเปˆเบ‡เปƒเบ™เบ—เบปเปˆเบงเบ›เบฐเป€เบ—เบ”. เปเบ•เปˆเบฅเบฐเบซเป‰เบญเบ‡เบเบฒเบ™เบกเบต Router WAN เบ—เบตเปˆเบขเบธเบ”เบŠเปˆเบญเบ‡เบ—เบฒเบ‡เบเบฒเบ™เบชเบทเปˆเบชเบฒเบ™เบˆเบฒเบเบœเบนเป‰เบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™เบ—เบตเปˆเปเบ•เบเบ•เปˆเบฒเบ‡เบเบฑเบ™. เป‚เบ›เบฃเป‚เบ•เบ„เปเบเบฒเบ™เบเบณเบ™เบปเบ”เป€เบชเบฑเป‰เบ™เบ—เบฒเบ‡เปเบกเปˆเบ™ BGP. routers WAN เบกเบตเบชเบญเบ‡เบ›เบฐเป€เบžเบ”: Cisco ISG เบซเบผเบท Juniper SRX.

เปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™เบงเบฝเบเบ‡เบฒเบ™: เบ—เปˆเบฒเบ™เบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เป„เบ”เป‰เบเปเบฒเบซเบ™เบปเบ”เบ„เปˆเบฒเป€เบ„เบทเบญเบ‚เปˆเบฒเบเบเปˆเบญเบเบชเบฐเป€เบžเบฒเบฐเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป€เบเบปเป‰เบฒเบฅเบฐเบงเบฑเบ‡เบงเบดเบ”เบตเป‚เบญเบขเบนเปˆเปƒเบ™เบžเบญเบ”เปเบเบเบ•เปˆเบฒเบ‡เบซเบฒเบเบเปˆเบฝเบงเบเบฑเบš router 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

เปเบกเปˆเปเบšเบš, เปเบ™เปˆเบ™เบญเบ™, เบšเปเปˆเบญเบญเบเบกเบฒเบˆเบฒเบเบญเบฒเบเบฒเบ”เบšเบฒเบ‡เป†. เป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เปเบกเปˆเบ™เบ„เบงเบฒเบกเปเบ•เบเบ•เปˆเบฒเบ‡เบ—เบตเปˆเบชเปเบฒเบ„เบฑเบ™เบฅเบฐเบซเบงเปˆเบฒเบ‡เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบ—เบตเปˆเป€เบ›เบฑเบ™เปเบฅเบฐเบซเบผเบฑเบ‡เบˆเบฒเบเบเบฒเบ™เปเบเป‰เป„เบ‚เบงเบฝเบเบ‡เบฒเบ™เปƒเบ™เบชเบญเบ‡ routers เบชเบฐเป€เบžเบฒเบฐเบ‚เบญเบ‡เปเบšเบšเบ—เบตเปˆเปเบ•เบเบ•เปˆเบฒเบ‡เบเบฑเบ™.

เบˆเบฒเบเปเบกเปˆเปเบšเบšเบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบžเบงเบเป€เบฎเบปเบฒเป€เบซเบฑเบ™เบงเปˆเบฒเป€เบžเบทเปˆเบญเปเบเป‰เป„เบ‚เบšเบฑเบ™เบซเบฒ, เบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เบžเบฝเบ‡เปเบ•เปˆเบชเบญเบ‡เบ•เบปเบงเบเปเบฒเบ™เบปเบ”เบเบฒเบ™เบชเปเบฒเบฅเบฑเบš Juniper เปเบฅเบฐ 3 เบ•เบปเบงเบเปเบฒเบ™เบปเบ”เบเบฒเบ™เบชเปเบฒเบฅเบฑเบš Cisco. เบ™เบตเป‰เบžเบงเบเป€เบ‚เบปเบฒเปเบกเปˆเบ™:

  • ifname
  • ipsuffix
  • asn

เปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™เบžเบงเบเป€เบฎเบปเบฒเบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เป„เบ”เป‰เบเปเบฒเบ™เบปเบ”เบ•เบปเบงเบเปเบฒเบ™เบปเบ”เบเบฒเบ™เป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เบชเปเบฒเบฅเบฑเบšเปเบ•เปˆเบฅเบฐเบญเบธเบ›เบฐเบเบญเบ™, i.e. เป€เบฎเบฑเบ”เบชเบดเปˆเบ‡เบ”เบฝเบงเบเบฑเบ™ เบชเบดเบ™เบ„เป‰เบฒเบ„เบปเบ‡เบ„เบฑเบ‡.

เป„เบ› เบชเบดเบ™เบ„เป‰เบฒเบ„เบปเบ‡เบ„เบฑเบ‡ เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบ›เบฐเบ•เบดเบšเบฑเบ”เบ•เบฒเบกเป€เบญเบเบฐเบชเบฒเบ™เบขเปˆเบฒเบ‡เป€เบ‚เบฑเป‰เบกเบ‡เบงเบ” เบเบฒเบ™เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™ Norir

เบ™เบฑเป‰เบ™เปเบกเปˆเบ™, เปƒเบซเป‰เบชเป‰เบฒเบ‡เป‚เบ„เบ‡เบเบฐเบ”เบนเบเป„เบŸเบฅเปŒเบ”เบฝเบงเบเบฑเบ™:

.
โ”œโ”€โ”€ 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, เบเบธเปˆเบก (เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ‚เบญเบ‡เบ‚เป‰เบญเบเป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เปเบกเปˆเบ™เป€เบ‚เบปเป‰เบฒเบชเบนเปˆเบฅเบฐเบšเบปเบš / เบฅเบฐเบซเบฑเบ”เบœเปˆเบฒเบ™) เปƒเบ™ เบเบธเปˆเบก.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

เปเบฅเบฐเบ™เบตเป‰เปเบกเปˆเบ™เบเบธเปˆเบก.yaml:

---
cisco:
    platform: ios
    username: admin1
    password: cisco1

juniper:
    platform: junos
    username: admin2
    password: juniper2

เบ™เบตเป‰เปเบกเปˆเบ™เบชเบดเปˆเบ‡เบ—เบตเปˆเป€เบเบตเบ”เบ‚เบถเป‰เบ™ เบชเบดเบ™เบ„เป‰เบฒเบ„เบปเบ‡เบ„เบฑเบ‡ เบชเปเบฒเบฅเบฑเบšเบงเบฝเบเบ‡เบฒเบ™เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒ. เปƒเบ™โ€‹เบฅเบฐโ€‹เบซเบงเปˆเบฒเบ‡โ€‹เบเบฒเบ™โ€‹เป€เบฅเบตเปˆเบกโ€‹เบ•เบปเป‰เบ™โ€‹, เบ•เบปเบงโ€‹เบเปเบฒโ€‹เบ™เบปเบ”โ€‹เบเบฒเบ™โ€‹เบˆเบฒเบโ€‹เป„เบŸเบฅโ€‹เปŒโ€‹เบชเบฒเบ‡โ€‹เปเบกเปˆเบ™โ€‹เบกเบตโ€‹เปเบœเบ™โ€‹เบ—เบตเปˆโ€‹เบเบฑเบšโ€‹เบฎเบนเบšโ€‹เปเบšเบšโ€‹เบงเบฑเบ”โ€‹เบ–เบธโ€‹ InventoryElement.

เบ‚เป‰เบฒเบ‡เบฅเบธเปˆเบกเบ™เบตเป‰ spoiler เปเบกเปˆเบ™เปเบœเบ™เบงเบฒเบ”เบ‚เบญเบ‡เบ•เบปเบงเปเบšเบš InventoryElement

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"
                }
            }
        }
    }
}

เบฎเบนเบšเปเบšเบšเบ™เบตเป‰เบชเบฒเบกเบฒเบ”เป€เบšเบดเปˆเบ‡เบชเบฑเบšเบชเบปเบ™เป€เบฅเบฑเบเบ™เป‰เบญเบ, เป‚เบ”เบเบชเบฐเป€เบžเบฒเบฐเปƒเบ™เบ•เบญเบ™เบ—เปเบฒเบญเบดเบ”. เปƒเบ™เบ„เปเบฒเบชเบฑเปˆเบ‡เบ—เบตเปˆเบˆเบฐเบ„เบดเบ”เบญเบญเบ, เบฎเบนเบšเปเบšเบšเบเบฒเบ™เป‚เบ•เป‰เบ•เบญเบšเปƒเบ™ python.

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

เปเบฅเบฐเบชเบธเบ”เบ—เป‰เบฒเบ, เปƒเบซเป‰เป€เบฎเบปเบฒเบเป‰เบฒเบงเป„เบ›เบชเบนเปˆเบชเบฐเบ„เบฃเบดเบšเป€เบญเบ‡. เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเบšเปเปˆเบกเบตเบซเบเบฑเบ‡เบ—เบตเปˆเบˆเบฐเบกเบตเบ„เบงเบฒเบกเบžเบนเบกเปƒเบˆเป‚เบ”เบเบชเบฐเป€เบžเบฒเบฐเบขเบนเปˆเบ—เบตเปˆเบ™เบตเป‰. เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเบžเบฝเบ‡เปเบ•เปˆเป€เบญเบปเบฒเบ•เบปเบงเบขเปˆเบฒเบ‡เบ—เบตเปˆเบžเป‰เบญเบกเบ—เบตเปˆเบˆเบฐเป€เบฎเบฑเบ”เบˆเบฒเบ เบเบฒเบ™เบชเบญเบ™ เปเบฅเบฐเปƒเบŠเป‰เบกเบฑเบ™เป€เบเบทเบญเบšเบšเปเปˆเบ›เปˆเบฝเบ™เปเบ›เบ‡. เบ™เบตเป‰เปเบกเปˆเบ™เบชเบดเปˆเบ‡เบ—เบตเปˆ script เบ—เบตเปˆเป€เบฎเบฑเบ”เบงเบฝเบเบชเปเบฒเป€เบฅเบฑเบ”เบฎเบนเบšเบ„เบท:

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.
เบ—เบตเปˆเบ™เบตเป‰เบ„เบทเบเบฑเบ™เบเบฑเบšเปƒเบ™ เบ•เบญเบšเบฎเบฑเบšเป„เบ”เป‰ เบเบฒเบ™เบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเป„เบ”เป‰เบ–เบทเบเบ›เบฐเบ•เบดเบšเบฑเบ”เปƒเบ™เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเบเบฑเบš router, เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบ”เบฑเบ”เปเบเป‰เปƒเบซเบกเปˆเป„เบ”เป‰เบ–เบทเบเบเบฐเบเบฝเบก, เป€เบŠเบดเปˆเบ‡เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เป„เบ”เป‰เบฎเบฑเบšเบเบฒเบ™เบเบงเบ”เบชเบญเบšเป‚เบ”เบเบญเบธเบ›เบฐเบเบญเบ™ (เปเบ•เปˆเบ™เบตเป‰เบšเปเปˆเปเบ™เปˆเบ™เบญเบ™; เบกเบฑเบ™เบ‚เบถเป‰เบ™เบเบฑเบšเบเบฒเบ™เบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™เบญเบธเบ›เบฐเบเบญเบ™เปเบฅเบฐเบเบฒเบ™เบˆเบฑเบ”เบ•เบฑเป‰เบ‡เบ›เบฐเบ•เบดเบšเบฑเบ”เป„เบ”เป€เบงเบตเปƒเบ™ NAPALM) , เปเบ•เปˆเบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเปƒเบซเบกเปˆเบšเปเปˆเป„เบ”เป‰เบ–เบทเบเบ™เปเบฒเปƒเบŠเป‰เป‚เบ”เบเบเบปเบ‡. เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบเบฒเบ™เบ•เปเปˆเบชเบนเป‰, เบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เป€เบญเบปเบฒเบžเบฒเบฅเบฒเบกเบดเป€เบ•เบตเบญเบญเบ dry_run เบซเบผเบทเบ›เปˆเบฝเบ™เบกเบนเบ™เบ„เปˆเบฒเบ‚เบญเบ‡เบกเบฑเบ™เป€เบ›เบฑเบ™ เบ—เบตเปˆเบšเปเปˆเบ–เบทเบเบ•เป‰เบญเบ‡.

เป€เบกเบทเปˆเบญเบชเบฐเบ„เบฃเบดเบšเบ–เบทเบเบ›เบฐเบ•เบดเบšเบฑเบ”, Nornir เบชเบปเปˆเบ‡เบšเบฑเบ™เบ—เบถเบเบฅเบฒเบเบฅเบฐเบญเบฝเบ”เปƒเบซเป‰เบเบฑเบš console.

เบ‚เป‰เบฒเบ‡เบฅเบธเปˆเบกเบ™เบตเป‰ spoiler เปเบกเปˆเบ™เบœเบปเบ™เบœเบฐเบฅเบดเบ”เบ‚เบญเบ‡ combat run เบชเบธเบ”เบชเบญเบ‡ routers เบเบฒเบ™เบ—เบปเบ”เบชเบญเบš:

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

เปƒเบ™เบ•เบญเบ™เบ•เบปเป‰เบ™เบ‚เบญเบ‡เบšเบปเบ”เบ„เบงเบฒเบกเบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰ overboard เบžเบฝเบ‡เป€เบฅเบฑเบเบ™เป‰เบญเบ เบ•เบญเบšเบฎเบฑเบšเป„เบ”เป‰, เปเบ•เปˆเบกเบฑเบ™เบšเปเปˆเปเบกเปˆเบ™เบชเบดเปˆเบ‡เบ—เบตเปˆเบšเปเปˆเบ”เบตเบ—เบฑเบ‡เบซเบกเบปเบ”. เบ‚เป‰เบญเบเบกเบฑเบเบžเบงเบเป€เบ‚เบปเบฒเปเบ—เป‰เป† vault เป€เบŠเบฑเปˆเบ™เบงเปˆเบฒ, เป€เบŠเบดเปˆเบ‡เบ–เบทเบเบญเบญเบเปเบšเบšเบกเบฒเป€เบžเบทเปˆเบญเป€เบŠเบทเปˆเบญเบ‡เบ‚เปเป‰เบกเบนเบ™เบ—เบตเปˆเบฅเบฐเบญเบฝเบ”เบญเปˆเบญเบ™เบญเบญเบเบˆเบฒเบเบชเบฒเบเบ•เบฒ. เปเบฅเบฐเบญเบฒเบ”เบˆเบฐเป€เบ›เบฑเบ™เบˆเปเบฒเบ™เบงเบ™เบซเบผเบฒเบเป„เบ”เป‰เบชเบฑเบ‡เป€เบเบ”เป€เบซเบฑเบ™เบงเปˆเบฒเบžเบงเบเป€เบฎเบปเบฒเบกเบตเบเบฒเบ™เป€เบ‚เบปเป‰เบฒเบชเบนเปˆเบฅเบฐเบšเบปเบš / เบฅเบฐเบซเบฑเบ”เบœเปˆเบฒเบ™เบ—เบฑเบ‡เบซเบกเบปเบ”เบชเปเบฒเบฅเบฑเบš routers เบชเบนเป‰เบฎเบปเบšเบ—เบฑเบ‡เบซเบกเบปเบ” sparkling เปƒเบ™เบฎเบนเบšเปเบšเบšเป€เบ›เบตเบ”เบขเบนเปˆเปƒเบ™เป„เบŸเบฅเปŒ. gorups.yaml. เบกเบฑเบ™เบšเปเปˆเบ‡เบฒเบก, เปเบ™เปˆเบ™เบญเบ™. เปƒเบซเป‰เบ›เบปเบเบ›เป‰เบญเบ‡เบ‚เปเป‰เบกเบนเบ™เบ™เบตเป‰เบ”เป‰เบงเบ vault.

เปƒเบซเป‰เบžเบงเบเป€เบฎเบปเบฒเป‚เบญเบ™เบžเบฒเบฅเบฒเบกเบดเป€เบ•เบตเบˆเบฒเบ 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

เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบ„เบดเบ”เป€เบซเบฑเบ™