Klassen und wie man sie setzt

Klassen sind wie Etikette und werden als Fallunterscheider genutzt; sie sind das if-then in CFEngine. Es gibt zwei Klassentypen:

Die eingebauten (built in) classes, auch Hardclasses: Diese Klassen erstellt CFEngine bei jedem agent-run (per default alle fünf Minuten) automatisch. Bspw. wird jedes Redhat-System mit der Class/Etikette "redhat" versehen und jedes SuSE-System mit "SLES" und ein SLES der Version 11 mit Service Pack 4 wird mit "SLES11_4" "etikettiert". Auch aus Hardware-Attributen des Systems generiert CFEngine Hardclasses. So hat jedes 64-Bit-System die Class "64_bit" und ein System auf einer x86_64 Architektur die Class "x86_64" und wenn das System eine CPU hat, hat es die Class "1_cpu". Somit kann man die Systeme exakt adressieren, will man alle Linux-Systeme, egal welches Devirat, die vier CPUs haben, adressieren, schreibt man vor das Promise:

    linux.4_cpu::  # KOMMENTAR: Der "." ist hier der UND-Operator, der die beiden Bedingungen/Klassen miteinander verknüpft.

Das liest der cf-agent dann "Bin ich ein Linux-System mit 4 CPUs? Dann geht mich das Folgende an, sonst überspringe ich es."
Weitere Beispiele für Hardclasses sind Uhrzeiten und Wochentage; mit beiden lassen sich Cronjobs via CFEngine einrichten.
Die Hardclasses kann man sich mit:

cf-promises --show-classes

ansehen.

Selbst definieren kann man die Soft-Classes. Man kann sie basierend auf dem Ergebnis eines vorhergegangenen Promises definieren oder basierend auf der Existenz einer anderen Klasse, einer Datei oder weiteren Begebenheiten, hier ein paar Beispiele:

Beispiel 1:

classes:
    "Datei_existiert" expression => fileexists("/Pfad/zur/Datei.endung");
    

Die Klasse "Datei_existiert" wird gesetzt, wenn Datei.endung existiert.

Beispiel 2:

    "30MinutenUptime" expressions => islessthan("30","$(sys.uptime)")

$(sys.uptime) ist eine CFEngine-interne Variable, die laut dem uptime-Befehl stets die Minuten kennt, wie lange der Server up ist. Die Class "30MinutenUptime" wird gesetzt, sobald 30 (Minuten) kleiner sind als die Uptime, dann sind eben 30 Minuten um.

Klassen lassen sich in Verbindung mit zuvor gesetzten Variablen setzen: Ich führe hier für jedes einzelne Beispiel var: und class: auf:

Beispiel 3:

vars:
    "meineServer" slist => ("ipv4_10_0_5");

classes:
    "meineServer" or => {@(meineServer)};
    

Variablen und Klassen dürfen die gleichen Namen haben. Die Variable hier ist eine Liste einer Zeichenkette (StringList/slist), in die automatisch alle Server reinkommen, die in diesem Netzwerksegment sind. Mit dieser Klasse können dann alle Server dieses Netzes addressiert werden.

Beispiel 4:

vars:
    "Schluessel" string => execresult("cat /die/Datei/mit/dem/Schluessel.key",useshell);
    

Hier führt der cf-agent das cat Kommando auf die Datei aus und schreibt die Ausgabe in die Variable "Schluessel". Nun kann man eine Klasse in Abhängigkeit von dieser Ausgabe definieren:

classes:
    "korrekterSchluessel" expression => strcmp("$(Schluessel)", "String_des_Schluessels");
    

Der cf-agent vergleicht den Inhalt der Variablen Schluessel mit der danach angegebenen Zeichenkette. Sind beide Zeichenketten gleich, wird "korrekterSchluessel" gesetzt, anderenfalls nicht; möchte man ggf. auf einen anderen Schlüssel testen und weitere Schritte davon abhängig machen, kann man hier die Abfragebedingung bzw. Class "!korrekterSchluessel" verwenden.

Beispiel 5:

vars:
   "meineDatei" string => translatepath("/Pfad/zu/meiner/Datei.endung");
   

translatepath nimmt eine Zeichenkette, die durch Slashes getrennt ist und übersetzt diese in das Format des Systems des Servers. CFEngine funktioniert ebenfalls auf Windows-Maschinen und würde auf einem Windows-Server die Slashes in Backslashes transformieren.

 classes:
     "Datei_existiert" expression => fileexists("$(meineDatei)";
     

Das ist wie das erste Beispiel, nur dass hier bei fileexists die Variable (anstatt des absoluten Pfades zur Datei) verwendet wird.