Nornir เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจ เจจเฉˆเฉฑเจŸเจตเจฐเจ• เจกเจฟเจตเจพเจˆเจธ เจ•เฉŒเจ‚เจซเจฟเจ—เจฐเฉ‡เจธเจผเจจ เจเจฒเฉ€เจฎเฉˆเจ‚เจŸเจธ เจจเฉ‚เฉฐ เจ†เจŸเฉ‹เจฎเฉˆเจŸเจฟเจ• เจฌเจฃเจพเจ‰เจฃเจพ เจ…เจคเฉ‡ เจญเจฐเจจเจพ

Nornir เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจ เจจเฉˆเฉฑเจŸเจตเจฐเจ• เจกเจฟเจตเจพเจˆเจธ เจ•เฉŒเจ‚เจซเจฟเจ—เจฐเฉ‡เจธเจผเจจ เจเจฒเฉ€เจฎเฉˆเจ‚เจŸเจธ เจจเฉ‚เฉฐ เจ†เจŸเฉ‹เจฎเฉˆเจŸเจฟเจ• เจฌเจฃเจพเจ‰เจฃเจพ เจ…เจคเฉ‡ เจญเจฐเจจเจพ

เจนเฉ‡ เจนเจฌเจฐ!

เจนเจพเจฒ เจนเฉ€ เจตเจฟเฉฑเจš เจ‡เฉฑเจฅเฉ‡ เจ‡เฉฑเจ• เจฒเฉ‡เจ– เจธเจพเจนเจฎเจฃเฉ‡ เจ†เจ‡เจ† เจนเฉˆเฅค เจฎเจพเจˆเจ•เฉเจฐเฉ‹เจŸเจฟเจ• เจ…เจคเฉ‡ LinuxเจฐเฉเจŸเฉ€เจจ เจ…เจคเฉ‡ เจ†เจŸเฉ‹เจฎเฉ‡เจธเจผเจจ เจœเจฟเฉฑเจฅเฉ‡ เจœเฉˆเจตเจฟเจ• เจ‡เฉฐเจงเจจ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจ‡เฉฑเจ• เจธเจฎเจพเจจ เจธเจฎเฉฑเจธเจฟเจ† เจฆเจพ เจนเฉฑเจฒ เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจธเฉ€เฅค เจ…เจคเฉ‡ เจนเจพเจฒเจพเจ‚เจ•เจฟ เจ‡เจน เจธเจฎเฉฑเจธเจฟเจ† เจชเฉ‚เจฐเฉ€ เจคเจฐเฉเจนเจพเจ‚ เจ†เจฎ เจนเฉˆ, Habr 'เจคเฉ‡ เจ‡เจธ เจตเจฐเจ—เจพ เจ•เฉเจ เจตเฉ€ เจจเจนเฉ€เจ‚ เจนเฉˆเฅค เจฎเฉˆเจ‚ เจธเจคเจฟเจ•เจพเจฐเจฏเฉ‹เจ— IT เจญเจพเจˆเจšเจพเจฐเฉ‡ เจจเฉ‚เฉฐ เจ†เจชเจฃเจพ เจนเฉฑเจฒ เจชเฉ‡เจธเจผ เจ•เจฐเจจ เจฆเจพ เจ‰เฉฑเจฆเจฎ เจ•เจฐเจพเจ‚เจ—เจพเฅค

เจ‡เจน เจ‡เจธ เจฎเจ•เจธเจฆ เจฒเจˆ เจคเจฟเจ†เจฐ เจ•เฉ€เจคเฉ€ เจ—เจˆ เจชเจนเจฟเจฒเฉ€ เจฌเจพเจˆเจ• เจจเจนเฉ€เจ‚ เจนเฉˆเฅค เจชเจนเจฟเจฒเจพ เจตเจฐเจœเจจ เจ•เจˆ เจธเจพเจฒ เจชเจนเจฟเจฒเจพเจ‚ เจฌเจฃเจพเจ‡เจ† เจ—เจฟเจ† เจธเฉ€เฅค เจœเจตเจพเจฌเจฆเฉ‡เจน เจตเจฐเจœเจจ 1.x.x. เจธเจพเจˆเจ•เจฒ เจฌเจนเฉเจค เจ˜เฉฑเจŸ เจตเจฐเจคเจฟเจ† เจœเจพเจ‚เจฆเจพ เจธเฉ€ เจ…เจคเฉ‡ เจ‡เจธ เจฒเจˆ เจ‡เจธเจจเฉ‚เฉฐ เจฒเจ—เจพเจคเจพเจฐ เจœเฉฐเจ—เจพเจฒ เจฒเฉฑเจ— เจœเจพเจ‚เจฆเจพ เจธเฉ€เฅค เจ‡เจธ เจ…เจฐเจฅ เจตเจฟเฉฑเจš เจ•เจฟ เจธเจฎเฉฑเจธเจฟเจ† เจ†เจชเจฃเฉ‡ เจ†เจช เจตเจฟเฉฑเจš เจตเจฐเจœเจจ เจ…เฉฑเจชเจกเฉ‡เจŸ เจœเจฟเฉฐเจจเฉ€ เจตเจพเจฐ เจจเจนเฉ€เจ‚ เจ†เจ‰เจ‚เจฆเฉ€เฅค เจœเจตเจพเจฌเจฆเฉ‡เจนเจ…เจคเฉ‡ เจนเจฐ เจตเจพเจฐ เจœเจฆเฉ‹เจ‚ เจฎเฉˆเจจเฉ‚เฉฐ เจธเจตเจพเจฐเฉ€ เจ•เจฐเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉเฉฐเจฆเฉ€ เจนเฉˆ, เจคเจพเจ‚ เจšเฉ‡เจจ เจกเจฟเฉฑเจ— เจœเจพเจ‚เจฆเฉ€ เจนเฉˆ, เจœเจพเจ‚ เจชเจนเฉ€เจ† เจกเจฟเฉฑเจ— เจœเจพเจ‚เจฆเจพ เจนเฉˆเฅค เจนเจพเจฒเจพเจ‚เจ•เจฟ, เจชเจนเจฟเจฒเจพ เจนเจฟเฉฑเจธเจพ, เจธเฉฐเจฐเจšเจจเจพเจตเจพเจ‚ เจคเจฟเจ†เจฐ เจ•เจฐเจฆเจพ เจนเฉˆ, เจนเจฎเฉ‡เจธเจผเจพ เจฌเจนเฉเจค เจตเจงเฉ€เจ† เจ•เฉฐเจฎ เจ•เจฐเจฆเจพ เจนเฉˆ, เจธเจผเฉเจ•เจฐ เจนเฉˆเฅค jinja2 เจ‡เฉฐเจœเจฃ เจšเฉฐเจ—เฉ€ เจคเจฐเฉเจนเจพเจ‚ เจธเจฅเจพเจชเจฟเจค เจนเฉˆเฅค เจชเจฐ เจฆเฉ‚เจœเจพ เจนเจฟเฉฑเจธเจพโ€”เจธเฉฐเจฐเจšเจจเจพเจตเจพเจ‚ เจจเฉ‚เฉฐ เจคเฉˆเจจเจพเจค เจ•เจฐเจจเจพโ€”เจ†เจฎ เจคเฉŒเจฐ 'เจคเฉ‡ เจนเฉˆเจฐเจพเจจเฉ€เจ†เจ‚ เจฒเจฟเจ†เจ‰เจ‚เจฆเจพ เจนเฉˆเฅค เจ…เจคเฉ‡ เจ•เจฟเจ‰เจ‚เจ•เจฟ เจฎเฉˆเจจเฉ‚เฉฐ เจธเฉฐเจฐเจšเจจเจพ เจจเฉ‚เฉฐ เจฐเจฟเจฎเฉ‹เจŸเจฒเฉ€ เจชเฉฐเจœเจพเจน เจกเจฟเจตเจพเจˆเจธเจพเจ‚ 'เจคเฉ‡ เจคเฉˆเจจเจพเจค เจ•เจฐเจจเจพ เจชเฉˆเจ‚เจฆเจพ เจนเฉˆ, เจœเจฟเจจเฉเจนเจพเจ‚ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจ•เฉเจ เจนเจœเจผเจพเจฐเจพเจ‚ เจ•เจฟเจฒเฉ‹เจฎเฉ€เจŸเจฐ เจฆเฉ‚เจฐ เจนเจจ, เจ‡เจธ เจŸเฉ‚เจฒ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจเจพ เจฅเฉ‹เฉœเฉเจนเจพ เจฎเฉเจธเจผเจ•เจฒ เจธเฉ€เฅค

เจ‡เฉฑเจฅเฉ‡ เจฎเฉˆเจจเฉ‚เฉฐ เจ‡เจน เจธเจตเฉ€เจ•เจพเจฐ เจ•เจฐเจจเจพ เจชเจตเฉ‡เจ—เจพ เจ•เจฟ เจฎเฉ‡เจฐเฉ€ เจ…เจจเจฟเจธเจผเจšเจฟเจคเจคเจพ เจธเฉฐเจญเจพเจตเจค เจคเฉŒเจฐ 'เจคเฉ‡ เจฎเฉ‡เจฐเฉ€ เจœเจพเจฃ-เจชเจ›เจพเจฃ เจฆเฉ€ เจ˜เจพเจŸ เจตเจฟเฉฑเจš เจœเฉœเฉเจน เจนเฉˆ เจœเจตเจพเจฌเจฆเฉ‡เจน, เจ‡เจธเจฆเฉ€เจ†เจ‚ เจ•เจฎเฉ€เจ†เจ‚ เจฆเฉ€ เจฌเจœเจพเจเฅค เจ…เจคเฉ‡ เจ‡เจน, เจตเฉˆเจธเฉ‡, เจ‡เฉฑเจ• เจฎเจนเฉฑเจคเจตเจชเฉ‚เจฐเจจ เจจเฉเจ•เจคเจพ เจนเฉˆเฅค เจœเจตเจพเจฌเจฆเฉ‡เจน โ€” เจ‡เฉฑเจ• เจชเฉ‚เจฐเฉ€ เจคเจฐเฉเจนเจพเจ‚ เจตเฉฑเจ–เจฐเจพ เจนเฉˆ, เจ‡เจธเจฆเจพ เจ†เจชเจฃเจพ เจ—เจฟเจ†เจจ เจ–เฉ‡เจคเจฐ เจนเฉˆ เจœเจฟเจธเจฆเฉ€ เจ†เจชเจฃเฉ€ DSL (เจกเฉ‹เจฎเฉ‡เจจ เจธเจชเฉˆเจธเฉ€เจซเจฟเจ• เจฒเฉˆเจ‚เจ—เจตเฉ‡เจœ) เจนเฉˆ, เจœเจฟเจธเจฆเจพ เจธเจฎเจฐเจฅเจจ เจ‡เฉฑเจ• เจญเจฐเฉ‹เจธเฉ‡เจฎเฉฐเจฆ เจชเฉฑเจงเจฐ 'เจคเฉ‡ เจ•เฉ€เจคเจพ เจœเจพเจฃเจพ เจšเจพเจนเฉ€เจฆเจพ เจนเฉˆเฅค เจ–เฉˆเจฐ, เจ…เจคเฉ‡ เจ‡เจน เจจเฉเจ•เจคเจพ เจ•เจฟ เจœเจตเจพเจฌเจฆเฉ‡เจน เจ‡เจน เจ•เจพเจซเจผเฉ€ เจคเฉ‡เจœเจผเฉ€ เจจเจพเจฒ เจตเจฟเจ•เจธเจค เจนเฉเฉฐเจฆเจพ เจนเฉˆ, เจ…เจคเฉ‡ เจชเจฟเจ›เฉœเฉ‡ เจ…เจจเฉเจ•เฉ‚เจฒเจคเจพ เจฆเฉ€ เจฌเจนเฉเจคเฉ€ เจชเจฐเจตเจพเจน เจ•เฉ€เจคเฉ‡ เจฌเจฟเจจเจพเจ‚, เจœเฉ‹ เจตเจฟเจธเจผเจตเจพเจธ เจจเฉ‚เฉฐ เจชเฉเจฐเฉ‡เจฐเจฟเจค เจจเจนเฉ€เจ‚ เจ•เจฐเจฆเจพเฅค

เจ‡เจธเฉ‡ เจฒเจˆ เจธเจพเจˆเจ•เจฒ เจฆเจพ เจฆเฉ‚เจœเจพ เจธเฉฐเจธเจ•เจฐเจฃ เจนเจพเจฒ เจนเฉ€ เจตเจฟเฉฑเจš เจœเจพเจฐเฉ€ เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจธเฉ€เฅค เจ‡เจธ เจตเจพเจฐ, เจชเจพเจ‡เจฅเจจ, เจœเจพเจ‚ เจนเฉ‹เจฐ เจธเจชเจธเจผเจŸ เจคเฉŒเจฐ 'เจคเฉ‡, เจ‡เฉฑเจ• เจขเจพเจ‚เจšเฉ‡ 'เจคเฉ‡ เจœเฉ‹ เจตเจฟเฉฑเจš เจฒเจฟเจ–เจฟเจ† เจ—เจฟเจ† เจนเฉˆ เจชเจพเจ‡เจฅเจจ เจ…เจคเฉ‡ เจฒเจˆ เจชเจพเจ‡เจฅเจจ เจจเจพเจฎ เจนเฉ‡เจ  เจจเฉŒเจฐเจจเฉ€เจฐ

เจคเจพเจ‚ - เจจเฉŒเจฐเจจเฉ€เจฐ เจ‡เจน เจ‡เฉฑเจ• เจฎเจพเจˆเจ•เฉเจฐเฉ‹เจซเฉเจฐเฉ‡เจฎเจตเจฐเจ• เจนเฉˆ เจœเจฟเจธ เจตเจฟเฉฑเจš เจฒเจฟเจ–เจฟเจ† เจ—เจฟเจ† เจนเฉˆ เจชเจพเจ‡เจฅเจจ เจ…เจคเฉ‡ เจฒเจˆ เจชเจพเจ‡เจฅเจจ เจ…เจคเฉ‡ เจ†เจŸเฉ‹เจฎเฉ‡เจธเจผเจจ เจฒเจˆ เจคเจฟเจ†เจฐ เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจนเฉˆเฅค เจฌเจฟเจฒเจ•เฉเจฒ เจœเจฟเจตเฉ‡เจ‚ เจ•เจฟ เจฆเฉ‡ เจฎเจพเจฎเจฒเฉ‡ เจตเจฟเฉฑเจš เจœเจตเจพเจฌเจฆเฉ‡เจนเจ‡เฉฑเจฅเฉ‡ เจธเจฎเฉฑเจธเจฟเจ†เจตเจพเจ‚ เจจเฉ‚เฉฐ เจนเฉฑเจฒ เจ•เจฐเจจ เจฒเจˆ, เจธเจนเฉ€ เจกเฉ‡เจŸเจพ เจคเจฟเจ†เจฐเฉ€ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ, เจญเจพเจต, เจนเฉ‹เจธเจŸเจพเจ‚ เจ…เจคเฉ‡ เจ‰เจนเจจเจพเจ‚ เจฆเฉ‡ เจชเฉˆเจฐเจพเจฎเฉ€เจŸเจฐเจพเจ‚ เจฆเฉ€ เจ‡เฉฑเจ• เจธเฉ‚เจšเฉ€, เจชเจฐ เจธเจ•เฉเจฐเจฟเจชเจŸเจพเจ‚ เจ‡เฉฑเจ• เจตเฉฑเจ–เจฐเฉ‡ DSL เจตเจฟเฉฑเจš เจจเจนเฉ€เจ‚, เจธเจ—เฉ‹เจ‚ เจฌเจนเฉเจค เจชเฉเจฐเจพเจฃเฉ€ เจจเจนเฉ€เจ‚, เจชเจฐ เจฌเจนเฉเจค เจตเจงเฉ€เจ† Python เจตเจฟเฉฑเจš เจฒเจฟเจ–เฉ€เจ†เจ‚ เจ—เจˆเจ†เจ‚ เจนเจจเฅค

เจ†เจ“ เจนเฉ‡เจ เจพเจ‚ เจฆเจฟเฉฑเจคเฉ€ เจ…เจธเจฒ-เจœเฉ€เจตเจจ เจ‰เจฆเจพเจนเจฐเจฃ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจตเฉ‡เจ–เฉ€เจ เจ•เจฟ เจ‡เจน เจ•เฉ€ เจนเฉˆเฅค

เจฎเฉ‡เจฐเจพ เจฆเฉ‡เจธเจผ เจญเจฐ เจตเจฟเฉฑเจš เจ•เจˆ เจฆเจฐเจœเจจ เจฆเจซเจผเจคเจฐเจพเจ‚ เจตเจพเจฒเจพ เจ‡เฉฑเจ• เจฌเฉเจฐเจพเจ‚เจš เจจเฉˆเฉฑเจŸเจตเจฐเจ• เจนเฉˆเฅค เจนเจฐเฉ‡เจ• เจฆเจซเจผเจคเจฐ เจตเจฟเฉฑเจš เจ‡เฉฑเจ• WAN เจฐเจพเจŠเจŸเจฐ เจนเฉเฉฐเจฆเจพ เจนเฉˆ เจœเฉ‹ เจตเฉฑเจ–-เจตเฉฑเจ– เจ†เจชเจฐเฉ‡เจŸเจฐเจพเจ‚ เจคเฉ‹เจ‚ เจ•เจˆ เจธเฉฐเจšเจพเจฐ เจšเฉˆเจจเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจ–เจคเจฎ เจ•เจฐเจฆเจพ เจนเฉˆเฅค เจฐเฉ‚เจŸเจฟเฉฐเจ— เจชเฉเจฐเฉ‹เจŸเฉ‹เจ•เฉ‹เจฒ BGP เจนเฉˆเฅค WAN เจฐเจพเจŠเจŸเจฐ เจฆเฉ‹ เจ•เจฟเจธเจฎเจพเจ‚ เจตเจฟเฉฑเจš เจ†เจ‰เจ‚เจฆเฉ‡ เจนเจจ: Cisco ISG เจœเจพเจ‚ Juniper SRXเฅค

เจนเฉเจฃ เจ•เฉฐเจฎ: เจฌเฉเจฐเจพเจ‚เจš เจจเฉˆเฉฑเจŸเจตเจฐเจ• เจฆเฉ‡ เจธเจพเจฐเฉ‡ WAN เจฐเจพเจŠเจŸเจฐเจพเจ‚ 'เจคเฉ‡ เจ‡เฉฑเจ• เจตเฉฑเจ–เจฐเฉ‡ เจชเฉ‹เจฐเจŸ 'เจคเฉ‡ เจตเฉ€เจกเฉ€เจ“ เจจเจฟเจ—เจฐเจพเจจเฉ€ เจฒเจˆ เจ‡เฉฑเจ• เจธเจฎเจฐเจชเจฟเจค เจธเจฌเจจเฉˆเฉฑเจŸ เจจเฉ‚เฉฐ เจ•เฉŒเจ‚เจซเจฟเจ—เจฐ เจ•เจฐเจจเจพ เจœเจผเจฐเฉ‚เจฐเฉ€ เจนเฉˆ - เจ‡เจธ เจธเจฌเจจเฉˆเฉฑเจŸ เจฆเจพ เจเจฒเจพเจจ BGP เจตเจฟเฉฑเจš เจ•เจฐเฉ‹ - เจธเจฎเจฐเจชเจฟเจค เจชเฉ‹เจฐเจŸ เจฆเฉ€ เจ—เจคเฉ€ เจธเฉ€เจฎเจพ เจจเฉ‚เฉฐ เจ•เฉŒเจ‚เจซเจฟเจ—เจฐ เจ•เจฐเฉ‹เฅค

เจชเจนเจฟเจฒเจพเจ‚, เจธเจพเจจเฉ‚เฉฐ เจ•เฉเจ เจŸเฉˆเจ‚เจชเจฒเฉ‡เจŸ เจคเจฟเจ†เจฐ เจ•เจฐเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ เจœเฉ‹ เจธเจฟเจธเจ•เฉ‹ เจ…เจคเฉ‡ เจœเฉ‚เจจเฉ€เจชเจฐ เจฒเจˆ เจตเฉฑเจ–เจฐเฉ‡ เจคเฉŒเจฐ 'เจคเฉ‡ เจธเฉฐเจฐเจšเจจเจพ เจคเจฟเจ†เจฐ เจ•เจฐเจจ เจฒเจˆ เจตเจฐเจคเฉ‡ เจœเจพเจฃเจ—เฉ‡เฅค เจธเจพเจจเฉ‚เฉฐ เจนเจฐเฉ‡เจ• เจฌเจฟเฉฐเจฆเฉ‚ เจ…เจคเฉ‡ เจ•เจจเฉˆเจ•เจธเจผเจจ เจชเฉˆเจฐเจพเจฎเฉ€เจŸเจฐเจพเจ‚ เจฒเจˆ เจกเฉ‡เจŸเจพ เจคเจฟเจ†เจฐ เจ•เจฐเจจ เจฆเฉ€ เจตเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ, เจฏเจพเจจเฉ€ เจ•เจฟ เจตเจธเจคเฉ‚ เจธเฉ‚เจšเฉ€ เจ‡เจ•เฉฑเจ เฉ€ เจ•เจฐเจจเฉ€เฅค

เจธเจฟเจธเจ•เฉ‹ เจฒเจˆ เจคเจฟเจ†เจฐ เจŸเฉˆเจ‚เจชเจฒเฉ‡เจŸ:

$ 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

เจŸเฉˆเจ‚เจชเจฒเฉ‡เจŸ, เจฌเฉ‡เจธเจผเฉฑเจ•, เจธเจฟเจฐเจซเจผ เจนเจตเจพ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจจเจนเฉ€เจ‚ เจ•เฉฑเจขเฉ‡ เจœเจพเจ‚เจฆเฉ‡เฅค เจ‡เจน เจตเฉฑเจ–-เจตเฉฑเจ– เจฎเจพเจกเจฒเจพเจ‚ เจฆเฉ‡ เจฆเฉ‹ เจ–เจพเจธ เจฐเจพเจŠเจŸเจฐเจพเจ‚ 'เจคเฉ‡ เจฆเจฟเฉฑเจคเฉ€ เจ—เจˆ เจธเจฎเฉฑเจธเจฟเจ† เจจเฉ‚เฉฐ เจนเฉฑเจฒ เจ•เจฐเจจ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ เจ•เฉฐเจฎ เจ•เจฐเจจ เจตเจพเจฒเฉ€เจ†เจ‚ เจธเฉฐเจฐเจšเจจเจพเจตเจพเจ‚ เจฆเฉ‡ เจฎเฉ‚เจฒ เจฐเฉ‚เจช เจตเจฟเฉฑเจš เจญเจฟเฉฐเจจ เจนเฉเฉฐเจฆเฉ‡ เจนเจจเฅค

เจธเจพเจกเฉ‡ เจŸเฉˆเจ‚เจชเจฒเฉ‡เจŸเจพเจ‚ เจคเฉ‹เจ‚, เจ…เจธเฉ€เจ‚ เจฆเฉ‡เจ–เจฆเฉ‡ เจนเจพเจ‚ เจ•เจฟ เจœเฉ‚เจจเฉ€เจชเจฐ เจฒเจˆ เจฆเฉ‹ เจชเฉˆเจฐเจพเจฎเฉ€เจŸเจฐ เจ…เจคเฉ‡ เจธเจฟเจธเจ•เฉ‹ เจฒเจˆ เจคเจฟเฉฐเจจ เจชเฉˆเจฐเจพเจฎเฉ€เจŸเจฐ เจธเจฎเฉฑเจธเจฟเจ† เจจเฉ‚เฉฐ เจนเฉฑเจฒ เจ•เจฐเจจ เจฒเจˆ เจ•เจพเจซเจผเฉ€ เจนเจจเฅค เจ‰เจน เจ‡เฉฑเจฅเฉ‡ เจนเจจ:

  • ifname
  • ip เจชเจฟเจ›เฉ‡เจคเจฐ
  • 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"

เจ…เจธเฉ€เจ‚ เจซเจพเจˆเจฒ เจตเจฟเฉฑเจš เจฎเฉเฉฑเจ– เจชเฉˆเจฐเจพเจฎเฉ€เจŸเจฐ เจฆเฉฑเจธเจพเจ‚เจ—เฉ‡เฅค เจนเฉ‹เจธเจŸเจธ.เจฏเจพเจฎเจฒ, เจธเจฎเฉ‚เจน (เจฎเฉ‡เจฐเฉ‡ เจฎเจพเจฎเจฒเฉ‡ เจตเจฟเฉฑเจš เจ‡เจน เจฒเจพเจ—เจ‡เจจ/เจชเจพเจธเจตเจฐเจก เจนเจจ) เจตเจฟเฉฑเจš เจ—เจฐเฉเฉฑเจชเจธ.เจฏเฉˆเจฎเจฒเจ…เจคเฉ‡ เจ…เฉฐเจฆเจฐ เจกเจฟเจซเจพเจฒเจŸ.เจฏเฉˆเจฎเจฒ เจ…เจธเฉ€เจ‚ เจ•เฉเจ เจตเฉ€ เจจเจนเฉ€เจ‚ เจฆเฉฑเจธเจพเจ‚เจ—เฉ‡, เจชเจฐ เจ‰เฉฑเจฅเฉ‡ เจคเจฟเฉฐเจจ เจ˜เจŸเจพเจ“ เจฒเจฟเจ–เจฃเฉ‡ เจœเจผเจฐเฉ‚เจฐเฉ€ เจนเจจ - เจ‡เจน เจฆเจฐเจธเจพเจ‰เจ‚เจฆเฉ‡ เจนเฉ‹เจ เจ•เจฟ เจ‡เจน เจนเฉˆ 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

เจ…เจคเฉ‡ เจ‡เจน groups.yaml เจนเฉˆ:

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

เจ‡เจน เจฎเจพเจกเจฒ เจฅเฉ‹เฉœเฉเจนเจพ เจ‰เจฒเจเจฃ เจตเจพเจฒเจพ เจนเฉ‹ เจธเจ•เจฆเจพ เจนเฉˆ, เจ–เจพเจธ เจ•เจฐเจ•เฉ‡ เจชเจนเจฟเจฒเจพเจ‚ เจคเจพเจ‚เฅค เจ‡เฉฐเจŸเจฐเจเจ•เจŸเจฟเจต เจฎเฉ‹เจก เจ‡เจธเจจเฉ‚เฉฐ เจธเจฎเจเจฃ เจตเจฟเฉฑเจš เจฌเจนเฉเจค เจฎเจฆเจฆเจ—เจพเจฐ เจนเฉˆเฅค เจ†เจˆเจชเจพเจˆเจฅเจจ.

 $ 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.
เจ‡เจน เจ‡เฉฑเจฅเฉ‡ เจตเฉ€ เจ‰เจนเฉ€ เจนเฉˆ เจœเฉ‹ เจตเจฟเฉฑเจš เจนเฉˆเฅค เจœเจตเจพเจฌเจฆเฉ‡เจน เจ‡เฉฑเจ• เจŸเฉˆเจธเจŸ เจฐเจจ เจฒเจพเจ—เฉ‚ เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจนเฉˆ, เจœเจฟเจธ เจฆเฉŒเจฐเจพเจจ เจฐเจพเจŠเจŸเจฐ เจจเจพเจฒ เจ‡เฉฑเจ• เจ•เจจเฉˆเจ•เจธเจผเจจ เจธเจฅเจพเจชเจค เจ•เฉ€เจคเจพ เจœเจพเจ‚เจฆเจพ เจนเฉˆ, เจ‡เฉฑเจ• เจจเจตเฉ€เจ‚ เจธเฉ‹เจงเฉ€ เจนเฉ‹เจˆ เจธเฉฐเจฐเจšเจจเจพ เจคเจฟเจ†เจฐ เจ•เฉ€เจคเฉ€ เจœเจพเจ‚เจฆเฉ€ เจนเฉˆ, เจœเจฟเจธเจจเฉ‚เฉฐ เจซเจฟเจฐ เจกเจฟเจตเจพเจˆเจธ เจฆเฉเจ†เจฐเจพ เจชเฉเจฐเจฎเจพเจฃเจฟเจค เจ•เฉ€เจคเจพ เจœเจพเจ‚เจฆเจพ เจนเฉˆ (เจชเจฐ เจ‡เจน เจจเจฟเจธเจผเจšเจฟเจค เจจเจนเฉ€เจ‚ เจนเฉˆ; เจ‡เจน เจกเจฟเจตเจพเจˆเจธ เจธเจนเจพเจ‡เจคเจพ เจ…เจคเฉ‡ NAPALM เจตเจฟเฉฑเจš เจกเจฐเจพเจˆเจตเจฐ เจฒเจพเจ—เฉ‚เจ•เจฐเจจ 'เจคเฉ‡ เจจเจฟเจฐเจญเจฐ เจ•เจฐเจฆเจพ เจนเฉˆ), เจชเจฐ เจจเจตเฉ€เจ‚ เจธเฉฐเจฐเจšเจจเจพ เจธเจฟเฉฑเจงเฉ‡ เจคเฉŒเจฐ 'เจคเฉ‡ เจฒเจพเจ—เฉ‚ เจจเจนเฉ€เจ‚ เจ•เฉ€เจคเฉ€ เจœเจพเจ‚เจฆเฉ€ เจนเฉˆเฅค เจ‰เจคเจชเจพเจฆเจจ เจตเจฐเจคเฉ‹เจ‚ เจฒเจˆ, เจชเฉˆเจฐเจพเจฎเฉ€เจŸเจฐ เจจเฉ‚เฉฐ เจนเจŸเจพเจ‡เจ† เจœเจพเจฃเจพ เจšเจพเจนเฉ€เจฆเจพ เจนเฉˆเฅค เจกเจฐเจพเจˆ_เจฐเจจ เจœเจพเจ‚ เจ‡เจธเจฆเจพ เจฎเฉเฉฑเจฒ เจ‡เจธ เจตเจฟเฉฑเจš เจฌเจฆเจฒเฉ‹ เจเฉ‚เจ เฉ‡.

เจธเจ•เฉเจฐเจฟเจชเจŸ เจšเจฒเจพเจ‰เจฃ เจตเฉ‡เจฒเฉ‡, เจจเฉŒเจฐเจจเจฟเจฐ เจ•เฉฐเจธเฉ‹เจฒ เจจเฉ‚เฉฐ เจตเจฟเจธเจคเฉเจฐเจฟเจค เจฒเฉŒเจ— เจ†เจ‰เจŸเจชเฉเฉฑเจŸ เจ•เจฐเจฆเจพ เจนเฉˆเฅค

เจธเจชเฉ‹เจ‡เจฒเจฐ เจฆเฉ‡ เจนเฉ‡เจ เจพเจ‚ เจฆเฉ‹ เจŸเฉˆเจธเจŸ เจฐเจพเจŠเจŸเจฐเจพเจ‚ 'เจคเฉ‡ เจฒเจพเจˆเจต เจฐเจจ เจฆเจพ เจ†เจ‰เจŸเจชเฉเฉฑเจŸ เจนเฉˆ:

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 เจตเจฟเฉฑเจš เจชเจพเจธเจตเจฐเจก เจฒเฉเจ•เจพเจ‰เจฃเจพ

เจฒเฉ‡เจ– เจฆเฉ€ เจธเจผเฉเจฐเฉ‚เจ†เจค เจตเจฟเฉฑเจš เจฎเฉˆเจ‚ เจฅเฉ‹เฉœเฉเจนเจพ เจœเจผเจฟเจ†เจฆเจพ เจ•เจฐ เจฆเจฟเฉฑเจคเจพ เจธเฉ€เฅค เจœเจตเจพเจฌเจฆเฉ‡เจน, เจชเจฐ เจ‰เฉฑเจฅเฉ‡ เจธเจญ เจ•เฉเจ เจ‡เฉฐเจจเจพ เจฎเจพเฉœเจพ เจจเจนเฉ€เจ‚ เจนเฉˆเฅค เจฎเฉˆเจจเฉ‚เฉฐ เจ‰เจน เจธเฉฑเจšเจฎเฉเฉฑเจš เจชเจธเฉฐเจฆ เจนเจจเฅค เจตเจพเจฒเจŸ เจฎเฉˆเจจเฉ‚เฉฐ เจ‡เจน เจชเจธเฉฐเจฆ เจนเฉˆ, เจœเฉ‹ เจ•เจฟ เจธเฉฐเจตเฉ‡เจฆเจจเจธเจผเฉ€เจฒ เจœเจพเจฃเจ•เจพเจฐเฉ€ เจจเฉ‚เฉฐ เจจเจœเจผเจฐ เจคเฉ‹เจ‚ เจฒเฉเจ•เจพเจ‰เจฃ เจฒเจˆ เจคเจฟเจ†เจฐ เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจนเฉˆเฅค เจ…เจคเฉ‡ เจฌเจนเฉเจค เจธเจพเจฐเฉ‡ เจฒเฉ‹เจ•เจพเจ‚ เจจเฉ‡ เจธเจผเจพเจ‡เจฆ เจฆเฉ‡เจ–เจฟเจ† เจนเฉ‹เจตเฉ‡เจ—เจพ เจ•เจฟ เจธเจพเจกเฉ‡ เจธเจพเจฐเฉ‡ เจฒเฉœเจพเจ•เฉ‚ เจฐเจพเจŠเจŸเจฐเจพเจ‚ เจฒเจˆ เจธเจพเจกเฉ‡ เจธเจพเจฐเฉ‡ เจฒเฉŒเจ—เจ‡เจจ เจ…เจคเฉ‡ เจชเจพเจธเจตเจฐเจก เจ‡เฉฑเจ• เจซเจพเจˆเจฒ เจตเจฟเฉฑเจš เจธเจชเจธเจผเจŸ เจคเฉŒเจฐ 'เจคเฉ‡ เจฆเจฟเจ–เจพเจˆ เจฆเจฟเฉฐเจฆเฉ‡ เจนเจจเฅค เจตเฉฑเจฒเฉ‹เจ‚ 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

เจ‡เจน เจฌเจนเฉเจค เจธเฉŒเจ–เจพ เจนเฉˆเฅค เจฌเจธ เจธเจพเจจเฉ‚เฉฐ เจธเจฟเจ–เจพเจ‰เจฃเจพ เจนเฉ€ เจฌเจพเจ•เฉ€ เจนเฉˆเฅค เจจเฉŒเจฐเจจเฉ€เจฐ- เจ‡เจธ เจกเฉ‡เจŸเจพ เจจเฉ‚เฉฐ เจชเฉเจฐเจพเจชเจค เจ•เจฐเจจ เจ…เจคเฉ‡ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจ เจฒเจˆ เจธเจ•เฉเจฐเจฟเจชเจŸเฅค
เจ‡เจน เจ•เจฐเจจ เจฒเจˆ, เจธเจพเจกเฉ€ เจธเจ•เฉเจฐเจฟเจชเจŸ เจตเจฟเฉฑเจš เจธเจผเฉเจฐเฉ‚เจ†เจคเฉ€ เจฒเจพเจˆเจจ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ 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 เจฆเฉ‡ เจจเจพเจฒ เจจเจนเฉ€เจ‚ เจนเฉ‹เจฃเจพ เจšเจพเจนเฉ€เจฆเจพเฅค เจชเจฐ เจ‡เจน เจ–เฉ‡เจกเจฃ เจฒเจˆ เจ เฉ€เจ• เจนเฉˆเฅค

เจนเฉเจฃ เจฒเจˆ เจฌเฉฑเจธ เจ‡เฉฐเจจเจพ เจนเฉ€เฅค เจฎเฉ‡เจฐเฉ‡ เจ•เฉ‹เจฒ เจธเจฟเจธเจ•เฉ‹ เจ…เจคเฉ‡ เจœเจผเฉˆเจฌเจฟเจ•เจธ เจฌเจพเจฐเฉ‡ เจ•เฉเจ เจนเฉ‹เจฐ เจฒเฉ‡เจ– เจœเจฒเจฆเฉ€ เจนเฉ€ เจ†เจ‰เจฃ เจตเจพเจฒเฉ‡ เจนเจจ, เจชเจฐ เจ‰เจน เจ†เจŸเฉ‹เจฎเฉ‡เจธเจผเจจ เจฌเจพเจฐเฉ‡ เจจเจนเฉ€เจ‚ เจนเจจเฅค เจ…เจคเฉ‡ เจจเฉ‡เฉœเจฒเฉ‡ เจญเจตเจฟเฉฑเจ– เจตเจฟเฉฑเจš, เจฎเฉˆเจ‚ เจธเจฟเจธเจ•เฉ‹ เจตเจฟเฉฑเจš RESTCONF เจฌเจพเจฐเฉ‡ เจฒเจฟเจ–เจฃ เจฆเฉ€ เจฏเฉ‹เจœเจจเจพ เจฌเจฃเจพ เจฐเจฟเจนเจพ เจนเจพเจ‚เฅค

เจธเจฐเฉ‹เจค: www.habr.com

DDoS เจธเฉเจฐเฉฑเจ–เจฟเจ†, VPS VDS เจธเจฐเจตเจฐเจพเจ‚ เจตเจพเจฒเฉ€เจ†เจ‚ เจธเจพเจˆเจŸเจพเจ‚ เจฒเจˆ เจญเจฐเฉ‹เจธเฉ‡เจฏเฉ‹เจ— เจนเฉ‹เจธเจŸเจฟเฉฐเจ— เจ–เจฐเฉ€เจฆเฉ‹ ๐Ÿ”ฅ DDoS เจธเฉเจฐเฉฑเจ–เจฟเจ†, VPS VDS เจธเจฐเจตเจฐเจพเจ‚ เจจเจพเจฒ เจญเจฐเฉ‹เจธเฉ‡เจฏเฉ‹เจ— เจตเฉˆเฉฑเจฌเจธเจพเจˆเจŸ เจนเฉ‹เจธเจŸเจฟเฉฐเจ— เจ–เจฐเฉ€เจฆเฉ‹ | ProHoster