Vergleichen Sie in Vorheriger Artikel die vordefinierten JSON-Daten mit den festgelegten JSON-Daten, um festzustellen, ob die Einstellungen wie erwartet wiedergegeben werden. tat. Dieses Mal möchte ich zwei JSON-Daten mit Ansible zusammenführen. Versuchen Sie insbesondere, bevor Sie die Einstellungen der Cisco IOS-XE-Schnittstelle in RESTCONF konfigurieren, vorhandene Einstellungen mit zusätzlichen Einstellungen zusammenzuführen.
Ich habe CSR1000v 16.9.3 von IOS XE auf CSR Recommended Code von Cisco DevNet Sandbox verwendet. Es war. Ich habe Ansible 2.9.2 in der virtuellen Umgebung von Python 3.6.8 installiert und verwendet.
Importiert JSONMerge als Ansible-Filter-Plug-In. Dies ist ein Python-basiertes Modul, das head (zusätzliche JSON-Daten) mit base (ursprüngliche JSON-Daten) zusammenführt und das Ergebnis ausgibt. Sie können die Zusammenführungsmethode unter Zusammenführungsstrategien angeben. Wenn nicht angegeben, wird es überschrieben und der alte Wert wird überschrieben. Eigentlich denke ich, dass es viele Fälle gibt, in denen Sie den Array-Daten "[〇, △]" Elemente hinzufügen möchten. In diesem Fall können Sie "Anhängen" (einfach hinzufügen) oder "arrayMergeById" auswählen (zusammenführen, wenn der spezifische Schlüsselwert im Element identisch ist, fügen Sie einen neuen hinzu). Ein Beispiel wird später vorgestellt, aber Sie können angeben, welche Daten verarbeitet werden sollen und wie sie auf dieselbe Weise wie JSON-Schema verarbeitet werden sollen.
Installieren Sie JSON Merge.
$ pip install jsonmerge
Ähnlich wie bei diesem Artikel werden die folgenden Dateien im Verzeichnis filter_plugins
gespeichert. (Tatsächlich werden auch andere benutzerdefinierte Filter in dieselbe Datei geschrieben.)
Was wir tun, sind die folgenden zwei Punkte.
HAS_JSONMERGE
installiert wirdcustom_filters1.py
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from ansible.module_utils.six import PY3, string_types
from ansible.errors import AnsibleError, AnsibleFilterError
try:
from jsonmerge import Merger
HAS_JSONMERGE = True
except ImportError:
HAS_JSONMERGE = False
class FilterModule(object):
def jsonmerge(self, output1, output2, schema):
if not HAS_JSONMERGE:
raise AnsibleFilterError("JSONMerge not found. Run 'pip install jsonmerge'")
merger = Merger(schema)
merge_result = merger.merge(output1, output2)
return merge_result
def filters(self):
return {
'jsonmerge': self.jsonmerge
}
Entspricht Vorheriger Artikel Ich habe etwas benutzt.
Playbook Der Inhalt jeder Aufgabe ist wie folgt.
Holen Sie sich die vorhandenen Schnittstelleneinstellungen mit dem Modul restconf_get
(1 der GigabieEthernet1 bis 3
wurde bereits eingestellt)
Geben Sie das Ergebnis von Aufgabe 1 aus
Definieren Sie in der Playbook-Variablen "content_data" die Einstellungen für "GigabitEthernet2" Beschreibung, Blockierung (kein Herunterfahren) und IP-Adresse.
Füge das Ergebnis von Task 1 mit content_data
mit dem Filter-Plug-in jsonmerge
zusammen.
Geben Sie zu diesem Zeitpunkt in der Taskvariablen "Schema" die Zusammenführungsstrategie der Schnittstelleneinstellung ("interface:") in "arrayMergeById" an. Geben Sie an, dass der Schnittstellenname die ID (idRef: name
) ist und dieselbe ID die Einstellungen zusammenführt.
playbook_restconf_int_merge1.yml
---
- hosts: cisco
gather_facts: no
vars:
content_data:
ietf-interfaces:interfaces:
interface:
- description: "For TEST"
enabled: true
ietf-ip:ipv4:
address:
- ip: 192.168.1.1
netmask: 255.255.255.0
name: GigabitEthernet2
tasks:
- name: get interface info # (1)
restconf_get:
path: /data/ietf-interfaces:interfaces
register: result_before
- name: display output data # (2)
debug:
msg: "{{ result_before.response }}"
- name: merge existing and setup interface settings # (3)
debug:
msg: "{{ result_before.response | jsonmerge(content_data, schema) }}"
vars:
schema:
properties:
ietf-interfaces:interfaces:
properties:
interface:
mergeStrategy: arrayMergeById
mergeOptions:
idRef: name
Wenn Sie sich das Ergebnis von Aufgabe 3 ansehen, können Sie sehen, dass sie problemlos zusammengeführt werden.
$ ansible-playbook -i inventory_restconf1.ini playbook_restconf_int_merge1.yml
PLAY [cisco] **********************************************************************************************************
TASK [get interface info] *********************************************************************************************
ok: [csr1000v-1]
TASK [display output data] ********************************************************************************************
ok: [csr1000v-1] => {
"msg": {
"ietf-interfaces:interfaces": {
"interface": [
{
"description": "MANAGEMENT INTERFACE - DON'T TOUCH ME",
"enabled": true,
"ietf-ip:ipv4": {
"address": [
{
"ip": "10.10.20.48",
"netmask": "255.255.255.0"
}
]
},
"ietf-ip:ipv6": {},
"name": "GigabitEthernet1",
"type": "iana-if-type:ethernetCsmacd"
},
{
"enabled": false,
"ietf-ip:ipv4": {},
"ietf-ip:ipv6": {},
"name": "GigabitEthernet2",
"type": "iana-if-type:ethernetCsmacd"
},
{
"description": "Network Interface",
"enabled": false,
"ietf-ip:ipv4": {},
"ietf-ip:ipv6": {},
"name": "GigabitEthernet3",
"type": "iana-if-type:ethernetCsmacd"
}
]
}
}
}
TASK [merge existing and setup interface settings] ********************************************************************
ok: [csr1000v-1] => {
"msg": {
"ietf-interfaces:interfaces": {
"interface": [
{
"description": "MANAGEMENT INTERFACE - DON'T TOUCH ME",
"enabled": true,
"ietf-ip:ipv4": {
"address": [
{
"ip": "10.10.20.48",
"netmask": "255.255.255.0"
}
]
},
"ietf-ip:ipv6": {},
"name": "GigabitEthernet1",
"type": "iana-if-type:ethernetCsmacd"
},
{
"description": "For TEST",
"enabled": true,
"ietf-ip:ipv4": {
"address": [
{
"ip": "192.168.1.1",
"netmask": "255.255.255.0"
}
]
},
"ietf-ip:ipv6": {},
"name": "GigabitEthernet2",
"type": "iana-if-type:ethernetCsmacd"
},
{
"description": "Network Interface",
"enabled": false,
"ietf-ip:ipv4": {},
"ietf-ip:ipv6": {},
"name": "GigabitEthernet3",
"type": "iana-if-type:ethernetCsmacd"
}
]
}
}
}
PLAY RECAP ************************************************************************************************************
csr1000v-1 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Fügen Sie als Referenz das Ergebnis der tatsächlichen Schnittstelleneinstellungen in das Modul "uri" ein.
playbook_restconf_int_merge2.yml
---
- hosts: cisco
gather_facts: no
vars:
content_data:
ietf-interfaces:interfaces:
interface:
- description: "For TEST"
enabled: true
ietf-ip:ipv4:
address:
- ip: 192.168.1.1
netmask: 255.255.255.0
name: GigabitEthernet2
tasks:
- name: merge interface settings
uri:
url: https://{{ansible_host}}:{{ansible_httpapi_port}}/restconf/data/ietf-interfaces:interfaces
method: PATCH
headers:
Content-Type: application/yang-data+json
Accept: application/yang-data+json
body_format: json
body: "{{ content_data | to_json }}"
status_code:
- 200
- 204
url_username: "{{ ansible_user }}"
url_password: "{{ ansible_password }}"
force_basic_auth: yes
validate_certs: no
- name: get interface info
restconf_get:
path: /data/ietf-interfaces:interfaces
register: result
- name: display output data
debug:
msg: "{{ result.response }}"
$ ansible-playbook -i inventory_restconf1.ini playbook_restconf_int_merge2.yml
PLAY [cisco] **********************************************************************************************************
TASK [merge interface settings] ***************************************************************************************
ok: [csr1000v-1]
TASK [get interface info] *********************************************************************************************
ok: [csr1000v-1]
TASK [display output data] ********************************************************************************************
ok: [csr1000v-1] => {
"msg": {
"ietf-interfaces:interfaces": {
"interface": [
{
"description": "MANAGEMENT INTERFACE - DON'T TOUCH ME",
"enabled": true,
"ietf-ip:ipv4": {
"address": [
{
"ip": "10.10.20.48",
"netmask": "255.255.255.0"
}
]
},
"ietf-ip:ipv6": {},
"name": "GigabitEthernet1",
"type": "iana-if-type:ethernetCsmacd"
},
{
"description": "For TEST",
"enabled": true,
"ietf-ip:ipv4": {
"address": [
{
"ip": "192.168.1.1",
"netmask": "255.255.255.0"
}
]
},
"ietf-ip:ipv6": {},
"name": "GigabitEthernet2",
"type": "iana-if-type:ethernetCsmacd"
},
{
"description": "Network Interface",
"enabled": false,
"ietf-ip:ipv4": {},
"ietf-ip:ipv6": {},
"name": "GigabitEthernet3",
"type": "iana-if-type:ethernetCsmacd"
}
]
}
}
}
PLAY RECAP ************************************************************************************************************
csr1000v-1 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
In diesem Fall wurde das erwartete Zusammenführungsergebnis erhalten. Wenn ich jedoch mehr als ein verschachteltes Array-Daten hinzufügen wollte, anstatt es zu überschreiben, trat ein Konflikt mit dem JSON-Schema auf und funktionierte nicht. Es mag einen Weg geben, dies zu tun, aber ich habe die Grenze meiner Energie erreicht und möchte es noch einmal versuchen: Schweiß:
Recommended Posts