Otomasi Jaringan dengan Ansible: command module

Berbicara tentang skenario khas otomatisasi jaringan, seseorang tidak dapat melakukannya tanpa satu set modul perintah. Berkat modul-modul ini, Ansible memungkinkan Anda untuk menjalankan perintah pada peralatan jaringan seolah-olah Anda memasukkannya langsung dari konsol. Pada saat yang sama, output dari perintah tidak hanya tergelincir di jendela terminal untuk tenggelam, tetapi dapat disimpan dan digunakan di masa depan. Itu dapat ditulis ke dalam variabel, diuraikan untuk digunakan dalam tugas-tugas berikutnya, atau disimpan untuk masa depan dalam variabel host.



Tujuan dari posting ini adalah untuk menunjukkan bahwa tugas manajemen jaringan yang berulang dapat diotomatisasi, dan Ansible tidak hanya memungkinkan Anda untuk mengelola konfigurasi, tetapi juga membantu menyingkirkan rutinitas dan menghemat waktu.

Mari kita menganalisis cara-cara dasar untuk menggunakan modul perintah jaringan, termasuk menyimpan output dari perintah menggunakan parameter register. Kami juga mempertimbangkan bagaimana skala ke beberapa perangkat jaringan menggunakan hostvars dan bagaimana mengatur eksekusi bersyarat menggunakan parameter wait_for dan tiga parameter terkait lainnya: interval, coba lagi dan cocok.

Platform jaringan yang berbeda memiliki modul perintah mereka sendiri, yang semuanya didukung di tingkat ekstensi Pengaya Jaringan Mesin Red Hat Ansible:

Platform jaringanModul * os_command
Arista eosperintah eos_
Cisco IOS / IOS-XEperintah ios_
Cisco IOS-XRiosxr_command
Cisco NX-OSnxos_command
Juniper Junosperintah junos_
Vyosperintah vyos_

Dasar-dasar modul perintah


Pertimbangkan buku pedoman yang hanya menjalankan perintah show show menggunakan modul eos_command:

--- - name: COMMAND MODULE PLAYBOOK hosts: eos connection: network_cli tasks: - name: EXECUTE ARISTA EOS COMMAND eos_command: commands: show version register: output - name: PRINT OUT THE OUTPUT VARIABLE debug: var: output 

Di sini kita memiliki dua tugas dan yang pertama menggunakan modul eos_command dengan parameter perintah tunggal. Karena kita hanya menjalankan satu perintah - tampilkan versi - ini dapat ditentukan pada baris yang sama dengan parameter perintah itu sendiri. Jika ada dua tim atau lebih, maka masing-masing dari mereka harus ditempatkan pada baris terpisah setelah perintah:. Dalam contoh ini, kami menggunakan kata kunci register untuk menyimpan output dari perintah show version. Parameter register (dapat digunakan dalam tugas Ansible) menetapkan variabel di mana output dari tugas kami akan disimpan sehingga dapat digunakan nanti. Dalam contoh kami, variabel ini disebut output.

Tugas kedua dalam contoh kami menggunakan modul debug untuk menampilkan isi dari variabel keluaran yang baru dibuat. Artinya, ini adalah data yang sama yang akan Anda lihat pada antarmuka baris perintah pada perangkat EOS jika Anda memasukkan "versi acara" di sana. Perbedaannya adalah bahwa buku pedoman kami akan menunjukkannya di jendela terminal tempat Anda meluncurkannya. Seperti yang Anda lihat, modul debug memudahkan untuk memeriksa variabel Ansible.

Ini adalah output dari buku pedoman kami:

 PLAY [eos] ************************************************************************* TASK [execute Arista eos command] ************************************************** ok: [eos] TASK [print out the output variable] *********************************************** ok: [eos] => { "output": { "changed": false, "failed": false, "stdout": [ "Arista vEOS\nHardware version: \nSerial number: \nSystem MAC address: 0800.27ec.005e\n\nSoftware image version: 4.20.1F\nArchitecture: i386\nInternal build version: 4.20.1F-6820520.4201F\nInternal build ID: 790a11e8-5aaf-4be7-a11a-e61795d05b91\n\nUptime: 1 day, 3 hours and 23 minutes\nTotal memory: 2017324 kB\nFree memory: 1111848 kB" ], "stdout_lines": [ [ "Arista vEOS", "Hardware version: ", "Serial number: ", "System MAC address: 0800.27ec.005e", "", "Software image version: 4.20.1F", "Architecture: i386", "Internal build version: 4.20.1F-6820520.4201F", "Internal build ID: 790a11e8-5aaf-4be7-a11a-e61795d05b91", "", "Uptime: 1 day, 3 hours and 23 minutes", "Total memory: 2017324 kB", "Free memory: 1111848 kB" ] ] } } PLAY RECAP ************************************************************************* eos : ok=2 changed=0 unreachable=0 failed=0 

Seperti yang dapat dilihat dari tangkapan layar, kedua tugas kami berhasil dengan sukses. Karena tugas pertama menggunakan tingkat detail detail pesan, ia hanya mengatakan bahwa host eos menyelesaikan tugas dengan hasil yang baik, menyoroti keberhasilan eksekusi berwarna hijau. Tugas kedua, dengan modul debug, mengembalikan output dari perintah yang dieksekusi, menampilkan informasi yang sama dalam dua format:

  • stdout
  • stdout_lines

Bagian stdout menunjukkan hal yang sama dengan yang Anda lihat di antarmuka baris perintah pada perangkat, tetapi dalam bentuk satu garis panjang. Dan bagian stdout_lines memecah output ini menjadi beberapa baris sehingga nyaman untuk dibaca. Setiap item dalam daftar ini adalah baris terpisah dalam output dari perintah.

Bandingkan output dari perintah di perangkat dan di Ansible:

Output tim di Arista EOSstdout_lines dalam Ansible
eos> tampilkan vers
Arista vEOS
Versi perangkat keras:
Nomor seri:
Alamat sistem MAC: 0800.27ec.005e

Versi gambar perangkat lunak: 4.20.1F
Arsitektur: i386
Versi build internal: 4.20.1F-6820520.4201F
ID build internal: 790a11e8-5aaf-4be7-a11a-e61795d05b91

Waktu aktif: 1 hari, 3 jam, dan 56 menit
Total memori: 2017324 kB
Memori bebas: 1116624 kB
"Stdout_lines": [
[
"Arista vEOS",
"Versi perangkat keras:",
"Nomor seri:",
"Sistem alamat MAC: 0800.27ec.005e",
"",
"Versi gambar perangkat lunak: 4.20.1F",
"Arsitektur: i386",
"Versi internal build:
4.20.1F-6820520.4201F ",
"ID build internal:
790a11e8-5aaf-4be7-a11a-e61795d05b91 ",
"",
"Waktu aktif: 1 hari, 3 jam dan 23 menit",
"Total memori: 2017324 kB",
"Memori bebas: 1111848 kB"
]

Jika Anda terbiasa dengan JSON dan YAML, maka Anda mungkin sudah memperhatikan satu keanehan: stdout_lines dimulai dengan dua tanda kurung:

 "stdout_lines": [ [ 

Dua tanda kurung buka menunjukkan bahwa stdout_lines sebenarnya mengembalikan daftar daftar baris. Jika Anda sedikit memodifikasi tugas debug kami, maka chip ini dapat digunakan untuk melihat hasil perintah secara selektif. Karena hanya ada satu daftar baris dalam daftar kami, daftar ini disebut nol (pada kenyataannya, ini adalah yang pertama, tetapi hitungannya dari awal). Sekarang mari kita lihat cara mengekstrak baris terpisah darinya, misalnya, Alamat Sistem MAC. Dalam output perintah, baris ini adalah baris keempat berturut-turut, tetapi karena kita menghitung dari awal, kita akhirnya membutuhkan baris 3 dari daftar 0, dengan kata lain: output.stdout_lines [0] [3].

  - name: print out a single line of the output variable debug: var: output.stdout_lines[0][3]   debug-   : TASK [print out a single line of the output variable] ****************************** ok: [eos] => { "output.stdout_lines[0][3]": "System MAC address: 0800.27ec.005e" } 

Apa gunanya penomoran daftar dan mengapa itu diperlukan? Faktanya adalah bahwa dalam tugas yang sama Anda dapat menjalankan beberapa tim, misalnya, seperti ini (di sini kami memiliki tiga tim):

 --- - hosts: eos connection: network_cli tasks: - name: execute Arista eos command eos_command: commands: - show version - show ip int br - show int status register: output - name: print out command debug: var: output.stdout_lines 

Seperti inilah hasilnya:

  "output.stdout_lines": [ [ "Arista vEOS", "Hardware version: ", "Serial number: ", "System MAC address: 0800.27ec.005e", "", "Software image version: 4.20.1F", "Architecture: i386", "Internal build version: 4.20.1F-6820520.4201F", "Internal build ID: 790a11e8-5aaf-4be7-a11a-e61795d05b91", "", "Uptime: 1 day, 4 hours and 20 minutes", "Total memory: 2017324 kB", "Free memory: 1111104 kB" ], [ "Interface IP Address Status Protocol MTU", "Ethernet1 172.16.1.1/24 up up 1500", "Management1 192.168.2.10/24 up up 1500" ], [ "Port Name Status Vlan Duplex Speed Type Flags", "Et1 connected routed full unconf EbraTestPhyPort ", "Et2 connected 1 full unconf EbraTestPhyPort ", "Et3 connected 1 full unconf EbraTestPhyPort ", "Ma1 connected routed a-full a-1G 10/100/1000" ] ] 

Di sini, daftar nomor nol adalah output dari perintah show version, daftar nomor satu adalah show ip int br output, daftar nomor dua adalah show int status output. Yaitu, nomor daftar ditentukan oleh urutan perintah dijalankan.

Tim EOS AristaMencocokkan Daftar Output
tampilkan versioutput.stdout_lines [0]
tampilkan ip int broutput.stdout_lines [1]
tampilkan status intoutput.stdout_lines [2]

Penskalaan modul perintah: variabel host


Dan apa yang terjadi jika Anda menjalankan playbook pada beberapa perangkat secara bersamaan?



Agar unik, variabel output disimpan sebagai variabel host untuk setiap host dalam inventaris. Jika kita memiliki tiga switch, dan kita menjalankan playbook kita pada mereka, kita akan mendapatkan variabel output untuk setiap host yang unik. Misalkan kita memerlukan alamat IP dari perintah show ip int br untuk port Ethernet1 pada switch03. Karena show ip int br adalah perintah kedua yang berjalan sebagai bagian dari tugas, dan data Ethernet1 terkandung di baris kedua dari outputnya, kita perlu menulis stdout_lines [1] [1]. Untuk mengakses variabel host tertentu, kami menggunakan kata kunci hostvars dan mencari host yang kami butuhkan berdasarkan nama.

Inilah cara melakukannya:

  - name: debug hostvar debug: var: hostvars["switch03"].output.stdout_lines[1][1] 

Akibatnya, output berisi apa yang kita butuhkan:

 TASK [debug hostvar] *************************************************************** ok: [switch03] => { "hostvars[\"switch03\"].output.stdout_lines[1][1]": "Ethernet1 172.16.1.3/24 up up 1500" } 

Secara default, tugas menggunakan variabel host saat ini, tetapi hostvars memungkinkan Anda untuk secara langsung mengakses variabel host lain.

Kondisi dalam tugas dengan modul perintah: wait_for parameter


Parameter wait_for memungkinkan Anda untuk mengimplementasikan pemeriksaan kondisi segera setelah perintah dijalankan. Misalnya, untuk membuat tugas dianggap berhasil diselesaikan hanya jika output dari perintah pemeriksaan status berisi teks tertentu. Secara default, parameter wait_for tidak digunakan, sehingga tugas hanya berjalan sekali, seperti pada contoh di atas. Tetapi jika Anda mengaturnya secara eksplisit, tugas akan dimulai kembali hingga kondisi terpenuhi atau batas upaya terlampaui (ada 10 secara default). Jika Anda mengaktifkan pembuatan perintah, Anda dapat melihat bahwa di playbook di bawah ini (yang ditulis secara khusus sehingga kondisinya tidak berlaku), semuanya terjadi begitu saja.

 --- - hosts: eos connection: network_cli tasks: - name: execute Arista eos command eos_command: commands: - show int status wait_for: - result[0] contains DURHAM 

Playbook ini akan menjalankan perintah show int status 10 kali, karena outputnya tidak akan pernah mengandung baris DURHAM.

Anda dapat memverifikasi ini menggunakan perintah show logging:

 Mar 24 20:33:52 eos Aaa: %ACCOUNTING-6-CMD: admin vty6 192.168.2.1 stop task_id=17 start_time=1521923632.5 timezone=UTC service=shell priv-lvl=15 cmd=show interfaces status Mar 24 20:33:53 eos Aaa: %ACCOUNTING-6-CMD: admin vty6 192.168.2.1 stop task_id=18 start_time=1521923633.71 timezone=UTC service=shell priv-lvl=15 cmd=show interfaces status Mar 24 20:33:54 eos Aaa: %ACCOUNTING-6-CMD: admin vty6 192.168.2.1 stop task_id=19 start_time=1521923634.81 timezone=UTC service=shell priv-lvl=15 cmd=show interfaces status Mar 24 20:33:55 eos Aaa: %ACCOUNTING-6-CMD: admin vty6 192.168.2.1 stop task_id=20 start_time=1521923635.92 timezone=UTC service=shell priv-lvl=15 cmd=show interfaces status Mar 24 20:33:56 eos Aaa: %ACCOUNTING-6-CMD: admin vty6 192.168.2.1 stop task_id=21 start_time=1521923636.99 timezone=UTC service=shell priv-lvl=15 cmd=show interfaces status Mar 24 20:33:58 eos Aaa: %ACCOUNTING-6-CMD: admin vty6 192.168.2.1 stop task_id=22 start_time=1521923638.07 timezone=UTC service=shell priv-lvl=15 cmd=show interfaces status Mar 24 20:33:59 eos Aaa: %ACCOUNTING-6-CMD: admin vty6 192.168.2.1 stop task_id=23 start_time=1521923639.22 timezone=UTC service=shell priv-lvl=15 cmd=show interfaces status Mar 24 20:34:00 eos Aaa: %ACCOUNTING-6-CMD: admin vty6 192.168.2.1 stop task_id=24 start_time=1521923640.32 timezone=UTC service=shell priv-lvl=15 cmd=show interfaces status Mar 24 20:34:01 eos Aaa: %ACCOUNTING-6-CMD: admin vty6 192.168.2.1 stop task_id=25 start_time=1521923641.4 timezone=UTC service=shell priv-lvl=15 cmd=show interfaces status Mar 24 20:34:02 eos Aaa: %ACCOUNTING-6-CMD: admin vty6 192.168.2.1 stop task_id=26 start_time=1521923642.47 timezone=UTC service=shell priv-lvl=15 cmd=show interfaces status 

Sekarang mari kita lihat contoh buku pedoman nyata di mana semuanya dikonfigurasi untuk membangun lingkungan OSPF (kedekatan) dengan perangkat selain perintah ip ospf area. Kami akan menggunakan perintah ini dan kemudian menggunakan parameter wait_for untuk memeriksa keberadaan kata FULL di output: jika ada, maka lingkungan telah berhasil dibuat. Jika FULL tidak muncul dalam 10 upaya, tugas akan gagal.

 --- - hosts: eos connection: network_cli tasks: - name: turn on OSPF for interface Ethernet1 eos_config: lines: - ip ospf area 0.0.0.0 parents: interface Ethernet1 - name: execute Arista eos command eos_command: commands: - show ip ospf neigh wait_for: - result[0] contains FULL 

Jalankan playbook ini menggunakan perintah ansible-playbook:

 ➜ ansible-playbook ospf.yml PLAY [eos] ********************************************************************************************* TASK [turn on OSPF for interface Ethernet1] ******************************************************* changed: [eos] TASK [execute Arista eos command] **************************************************************** ok: [eos] PLAY RECAP ****************************************************************************************** eos : ok=2 changed=1 unreachable=0 failed=0 

Kami melihat baris perintah dan melihat bahwa playbook berhasil:

 eos#show ip ospf neigh Neighbor ID VRF Pri State Dead Time Address Interface 2.2.2.2 default 1 FULL/DR 00:00:33 172.16.1.2 Ethernet1 

Selain mengandung, Anda dapat menggunakan operator perbandingan berikut:

  • eq: - sama
  • neq: - tidak sama
  • gt: - lebih banyak
  • ge: - lebih besar dari atau sama dengan
  • lt: - kurang
  • le: - kurang dari atau sama dengan

Selain itu, bersama dengan wait_for, Anda dapat menggunakan tiga parameter tambahan, (dijelaskan secara rinci dalam dokumentasi untuk modul):

ParameterDeskripsi
intervalWaktu antar repetisi tim.
coba lagiMaks jumlah pengulangan sebelum tugas selesai dengan kesalahan, atau kondisi terpenuhi.
cocokKebetulan dari semua kondisi atau setidaknya satu.

Mari kita membahas lebih detail tentang parameter kecocokan:

  - name: execute Arista eos command eos_command: commands: - show ip ospf neigh match: any wait_for: - result[0] contains FULL - result[0] contains 172.16.1.2 

Ketika kecocokan: ada yang ditentukan, tugas dianggap berhasil jika hasilnya berisi FULL atau 172.16.1.2. Jika cocok: semua ditentukan, maka hasilnya harus mengandung FULL dan 172.16.1.2. Secara default, cocok: semua digunakan, karena jika Anda meresepkan beberapa kondisi, maka kemungkinan besar Anda ingin semuanya dieksekusi, dan bukan setidaknya satu.

Kapan bisa cocok: ada yang berguna? Misalkan Anda perlu memverifikasi bahwa pusat data memiliki koneksi dua arah ke Internet. Dan pusat data terhubung ke lima penyedia Internet yang berbeda, masing-masing memiliki koneksi BGP sendiri. Buku pedoman dapat memeriksa semua lima koneksi ini, dan jika setidaknya salah satu dari mereka berfungsi, dan tidak semua lima, melaporkan bahwa semuanya beres. Ingatlah bahwa ada yang logis ATAU, dan semuanya adalah DAN logis.

ParameterDeskripsi
cocok: apa sajaLogis "atau"
Setidaknya satu syarat diperlukan
cocok: semuaLogis "dan"
Semua persyaratan diperlukan

Kondisi negatif: membangun logika terbalik


Terkadang penting bukan apa yang ada di kesimpulan, tetapi apa yang tidak ada di sana. Di sini, tentu saja, selalu tergoda untuk menggunakan operator perbandingan neq, tetapi untuk beberapa skenario dengan kondisi negatif ada opsi yang lebih baik. Misalnya, jika Anda perlu membalikkan pernyataan berisi (tipe, "output dari perintah tidak boleh mengandung ini dan itu"), Anda dapat menggunakan kata kunci register untuk menyimpan output, dan kemudian memprosesnya di tugas berikutnya menggunakan ekspresi when . Atau, misalnya, ketika Anda harus menghentikan playbook jika kondisinya tidak terpenuhi, cukup gunakan modul gagal atau konfirmasi untuk keluar secara khusus dengan kesalahan. Adapun operator perbandingan neq, itu hanya berguna ketika Anda dapat mengekstraksi nilai yang tepat dari output (misalnya, dari pasangan nilai kunci atau dari JSON), dan bukan hanya string atau daftar string. Jika tidak, perbandingan karakter dengan string akan dilakukan.

Apa selanjutnya


Baca dokumentasi tentang bekerja dengan output perintah dalam modul jaringan. Ini memberikan contoh berguna menggunakan ge, file, dan kondisi lainnya ketika bekerja dengan output format JSON pada platform jaringan tertentu.

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


All Articles