[PYTHON] Führen Sie Daten im JSON-Format mit Ansible zusammen

Einführung

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.

1. Vorbereitete Umgebung

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.

2. Filter-Plug-In

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.

2-1. Vorbereitungen

Installieren Sie JSON Merge.

$ pip install jsonmerge

2-2. Python-Code (Auszug)

Ä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.

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

3. Inventardatei

Entspricht Vorheriger Artikel Ich habe etwas benutzt.

  1. Playbook Der Inhalt jeder Aufgabe ist wie folgt.

  2. Holen Sie sich die vorhandenen Schnittstelleneinstellungen mit dem Modul restconf_get (1 der GigabieEthernet1 bis 3 wurde bereits eingestellt)

  3. Geben Sie das Ergebnis von Aufgabe 1 aus

  4. 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

5. Ausgabeergebnis

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  

(Referenz) Ändern Sie die Schnittstelleneinstellungen

Fügen Sie als Referenz das Ergebnis der tatsächlichen Schnittstelleneinstellungen in das Modul "uri" ein.

(Referenz 1) Playbook zum Ändern von Einstellungen

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

(Referenz 2) Ausgabeergebnis der Einstellungsänderung

$ 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 

Schließlich

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

Führen Sie Daten im JSON-Format mit Ansible zusammen
Formatieren Sie json mit Vim (mit Python)
Lesen von JSON-Daten mit Python
Exportieren Sie DB-Daten im JSON-Format
[Einführung in Python] Umgang mit Daten im JSON-Format
Konvertieren Sie Daten im JSON-Format in txt (mit yolo)
Flow Memo beim Abrufen von JSON-Daten mit urllib
Datenanalyse mit Python 2
Verwenden Sie ansible mit cygwin
[Python] Verwenden Sie JSON mit Python
Zusammenführen von Datensätzen mit Pandas
Daten mit TensorFlow lesen
json parsing mit gdb
Ausgabeprotokoll im JSON-Format mit Python-Standardprotokollierung
Datenvisualisierung mit Pandas
Lesen Sie die json-Datei mit Python, formatieren Sie sie und geben Sie json aus
Daten mit Pandas mischen
Datenerweiterung mit openCV
Daten mit Scipy normieren
SQL-Format mit sqlparse
LADEN SIE DATEN mit PyMysql
[Python] Verwenden Sie Daten im JSON-Format als Objekt vom Typ Wörterbuch
Mit Python erstellte Beispieldaten
Betten Sie Audiodaten in Jupyter ein
Zeichnen Sie Excel-Daten mit matplotlib (1)
Laden Sie verschachtelten Json mit Pandas
POST json mit Python 3-Skript
Datenverarbeitung 3 (Entwicklung) Informationen zum Datenformat
Extrahieren Sie Twitter-Daten mit CSV
Holen Sie sich Youtube-Daten mit Python
Schreiben Sie Daten im HDF-Format
Binarisieren Sie Fotodaten mit OpenCV
Zeichnen Sie Excel-Daten mit matplotlib (2)
Verwenden Sie Django, um Tweet-Daten zu speichern
Formatieren Sie die Sprachquelle C mit pycparser
Arbeiten mit JSON-Dateien in Matlab
String-Format mit Python% -Operator
Datenverarbeitungstipps mit Pandas
Holen Sie sich Makrelendaten und spucken Sie json aus, um ein dynamisches Inventar zu erhalten