2017-06-30 4 views
0

Ich habe Probleme bei der Verwendung mehrerer und/oder Bedingungen in einer WHEN-Anweisung zu entscheiden, ob eine Aufgabe ausgeführt werden muss oder nicht. Im Grunde mache ich ein Playbook, um automatisierte System-Patches mit Optionen für Sicherheits-Patches, nur Kernel-Patches und zum Angeben von Paketen in einer var-Datei durchzuführen.Ansible: Mehrere und/oder Bedingungen in WHEN-Klausel

betreibe ich das Textbuch mit den folgenden Befehlen und die Variablen durch erweiterte Variablen Option (-e)

ansible-playbook site.yml -i inventory --ask-vault -u (username) -e "security=true restart=true" -k -K

Standardmäßig definieren die Textbuch jedes Paket auf dem System außer Kernel aktualisiert wird, aber ich möchte um diese Aktion zu überspringen, wenn ich eine von einigen Variablen festlege. Der Code, den ich habe, ist die folgende:

- name: Update all packages 
    yum: 
    name: "*" 
    state: latest 
    exclude: "kernel*" 
    when: security is not defined or kernel is not defined or specified_packages 
is not defined and ansible_os_family == "RedHat" 

Ive alle folgenden Kombinationen versucht:

when: (ansible_os_family == "RedHat") and (security is defined or kernel is defined or specified_packages is defined)

when: (ansible_os_family == "RedHat") and (security == true or kernel == true or specified_packages == true) < - dieser Fall wirft einen Fehler nicht definiert, weil ich alle Variablen nicht definieren jedes Mal, wenn ich laufe das Textbuch

when: ansible_os_family == "RedHat" when: security is defined or kernel is defined or specified_packages is defined

Hinweis: Ich bin bewusst und habe eine zusätzliche Variable wie "Überspringen" verwendet, um diese Aufgabe zu überspringen und die Wobei-Klausel when: ansible_os_family == "RedHat" and skip is not defined verwenden, aber meine Benutzer möchten nicht eine zusätzliche Variable verwenden, nur um diese Standardaktion zu überspringen.

Ich verwende auch keine Tags, da ich eine Liste von Paketen vor und nach dem Upgrade sammle, um am Ende zu vergleichen und zu berichten, so dass ich diese nicht ausführen kann, da sie lokale Aktionsbefehle sind. Aus diesem Grund verwende ich eine Rolle mit mehreren Aufgaben, die über erweiterte Variablen ein- und ausgeschaltet werden. Ich bin offen für jeden Vorschlag, der das Spielbuch effizienter umgeschrieben hat, da ich eher ein Anfänger bin.

+0

Ja, Sie nicht 'ist defined' mit anderen Bedingungen auf diese Weise kombinieren können. Es wird nicht funktionieren, wenn eine Variable nicht definiert ist. – techraf

+0

So gibt es keine Möglichkeit, eine Aufgabe basierend darauf auszuführen, ob eine Liste von Variablen definiert ist oder nicht, zusammen mit einer Überprüfung auf OS? Es funktioniert für eine wie diese 'wenn: ansible_os_family und Sicherheit ist nicht definiert, aber nicht multiple ... – Jay

+0

Ja, es kann nur eine sein "ist definiert" und, wenn ich mich richtig erinnere, sollte es am Ende sein. Das Problem ist, dass Ansible intern immer eine Ausnahme hat, wenn eine Variable nicht definiert ist. Dann sucht es nach "definierter" Bedingung und wenn es da ist, behandelt es die Ausnahme, statt zu scheitern. Es kann jedoch nicht mehrere Bedingungen verarbeiten. Sie müssten den Code entweder so umgestalten, dass er "Standard" -Filter enthält, oder zusätzliche Fakten, nur um sie zu überprüfen. – techraf

Antwort

0

Es war so eine einfache Antwort!

Die folgenden Werke:

when: not (security is defined or kernel is defined or specified_packages is defined) and ansible_os_family == "RedHat"

1

Wie @techraf in den Kommentaren erwähnt, defined/undefined ist eine böse Test ...

Umgestalten wie folgt aus:

when: 
    - ansible_os_family == "RedHat" 
    - security|d('') != '' or kernel|d('') != '' or specified_packages|d('') != '' 

aktualisieren. Reproduzierbare Beispiel:

- hosts: localhost 
    gather_facts: no 
    tasks: 
    - debug: 
     msg: hello 
     when: 
     - '"RedHat" == "RedHat"' 
     - security|d('') != '' or kernel|d('') != '' or specified_packages|d('') != '' 

Ausführung:

ansible-playbook -e kernel=true playbook.yml 

PLAY [localhost] *************************************************************** 

TASK [debug] ******************************************************************* 
ok: [localhost] => { 
    "msg": "hello" 
} 

PLAY RECAP ********************************************************************* 
localhost     : ok=1 changed=0 unreachable=0 failed=0 

Versionen:

$ pip list | grep -iP 'ansible|jinja' 
ansible (2.2.1.0) 
Jinja2 (2.8) 
+0

Leider funktioniert es nur für einen..Wenn ich die erste Variable angeben, funktioniert es gut, aber wenn ich die zweite Variable angeben, wird der Fehler ausgelöst: '" Das Feld 'args' hat einen ungültigen Wert, der eine Variable enthält, die ist undefined Der Fehler war: 'Kernel' ist undefiniert \ n \ nDer Fehler scheint in ' – Jay

+0

gewesen zu sein Welche Versionen von Ansible und Jinja2 benutzen Sie? Dieser Ausdruck funktioniert gut mit den letzten Versionen: Er wird die Aufgabe ausführen, wenn os ist RedHat UND irgendein von Sicherheit/kernel/spezifizierten_Packages ist gesetzt. –

+0

Nicht sicher, wie man die Jinja Version überprüft, aber auf ansible 2.2.0 war gerade aktualisiert zu 2.3.1, um zu sehen, ob das funktioniert aber kein Glück. Die bedingte Prüfung für OS UND die Die erste definierte Variablenkombination funktioniert, aber wenn ich eine Variable definiere, die nicht im ersten Slot ist, wird ein Fehler ausgelöst, weil die erste Variable nicht definiert ist, zB wenn ich sage: kernel = true heißt es nicht definiert – Jay