Securing Elasticsearch

The English version of this post is available here.
Woah, was für ein Thema: Datenschutz
Und damit meine ich nicht das allseits bekannte Thema und die seit jeher leidenschaftlich verfochtenen persönlichen Daten. Nein, wovon ich rede sind die Daten, die in Elasticsearch landen. Wobei dort sicher auch bei dem einen oder anderen Personen bezogene Daten hinterlegt sind, keine Frage.
Viele setzen bereits diverse Lösungen ein, um den Zugriff auf Elasticsearch zu steuern. Das geht von einfachen URL-Filtern, über dedizierte Reverse Proxies mit Authentifizierung bis hin zu Elasticsearch’s hauseigener Rundum Lösung “Shield”. Doch was sie alle gemeinsam haben: Sie sind nicht für jeden geeignet, da sie entweder zu eingeschränkt hinsichtlich der Funktionalität oder schlicht zu teuer in der Anschaffung sind.
Deshalb kam eine namhafte Größe aus der Automobil-Branche auf uns zu, und schlug vor eine Opensource Lösung zu entwickeln, um all das in einem Produkt zu integrieren. Heraus kam ein von Grund auf neu geschriebener Reverse Proxy Dienst, welcher Authentifizierung und Autorisation auf Index-, Typ- und Feld-Ebene sowie auf Basis konkreter Funktionalitäten von Elasticsearch’s REST API vereint. Das ganze hat natürlich auch einen Namen: ElasticArmor
In der ersten Version werden zwar vorerst nur normale Anfragen die von Kibana stammen in vollem Umfang berücksichtigt, doch da das Projekt Opensource ist und mit der Absicht leicht zu erweitern zu sein geschrieben wurde, gehen wir davon aus nicht lange auf Erweiterungen warten zu müssen. Außerdem erfordert die Natur des Dienstes die zusätzliche Absicherung des angebundenen Elasticsearch-Cluster mittels eines Sicherheitsperimeters, da nur die Kommunikation zwischen Cient und Elasticsearch eingeschränkt wird, nicht jedoch die Kommunikation der einzelnen Elasticsearch-Nodes.
Doch wie funktioniert der ElasticArmor nun eigentlich? Nun, eigentlich ganz einfach. Ein Client der eine Anfrage an Elasticsearch stellt, muss zuerst am ElasticArmor vorbei. Ein Client ist, per Definition, der Ursprung der Anfrage. Dabei kann es sich um einen weiteren Dienst wie z.B. Kibana oder eine bestimmte Person handeln. Authentifizierung bedeutet allerdings nicht zwingend, dass es sich um eine reale Person mit Namen und Passwort handeln muss, es kann genauso gut ein anonymer Zugriff von einer ganz bestimmten IP sein.
Erhält der ElasticArmor nun letztendlich eine Anfrage von einem authentifizierten Client, werden die ihm zugeordneten Rollen angewendet. Diese definieren was und wie viel er darf. Angewendet werden sie, indem die URL der Anfrage und der Körper der selben analysiert werden. Im Falle der URL ist das nicht weiter schwer, doch der Körper einer Anfrage (z.B. Search-API) ist wesentlich komplexer. Aus diesem Grund ist dem ElasticArmor genau bekannt was für Möglichkeiten ein Client in einer solchen Anfrage hat. Trifft er auf etwas das ihm nicht bekannt ist, (z.B. ein neu eingeführtes Query) wird die Anfrage sofort abgelehnt. Dies verhindert Sicherheitslücken wenn die Version von Elasticsearch aktualisiert wird, ohne Rücksicht auf die Kompatibilität mit dem ElasticArmor zu nehmen.
Verändert wird eine Anfrage nur, wenn sich das Ergebnis nicht grundlegend ändert. Das bedeutet z.B. dass Queries, Filter, Aggregationen o.Ä. nicht verändert werden, die URL potentiell jedoch schon, jedenfalls was Indizes, Dokumente und Felder anbelangt. Auch das Source filtering wird verwendet um sicher zu stellen, dass jemand nur das sieht was er sehen darf.
Einige Features von Elasticsearch sind jedoch nur sehr schwer bis gar unmöglich einzuschränken, (z.B. Fuzzy Like This, Fuzzy Like This Field und More Like This) weshalb bei diesen nur das Recht sie zu benutzen sicher gestellt wird. Man sollte also aufpassen wem man dieses Recht gestattet.
Desweiteren verhält sich der ElasticArmor nach außen hin wie Elasticsearch. Schließlich ist er es mit dem sich ein Client tatsächlich unterhält. Somit sollte eine relativ problemlose Integration in die bereits bestehende Infrastruktur möglich sein.
Das war’s dann auch schon wieder. Ich hoffe ich konnte das Interesse, insbesondere die Vorfreude, bei dem einen oder anderen wecken. Bei Fragen, bitte einfach drauf los kommentieren!

Johannes Meyer
Johannes Meyer
Developer

Johannes ist seit 2011 bei uns und hilft bei der Entwicklung zukünftiger Knüller (Icinga2, Icinga Web 2, ...) aus dem Hause NETWAYS.

Bottle – Klein aber fein

Vor einiger Zeit war es notwendig für ein Kunden-Projekt dessen Umgebung bei uns nachzubilden. Es war von vornherein klar, dass es keine 1:1 Nachbildung sein muss (kann) und somit war es nur notwendig einige wenige Bestandteile einer REST Api zu simulieren. Da REST rein HTTP basiert ist und die zu simulierenden Aktionen nur GET waren, kam uns erst gar nicht in den Sinn ein großartiges PHP-Projekt ins Leben zu rufen und entschieden uns daher für eine schnelle Lösung mittels eines Standalone Python Skriptes.
Mir war Bottle schon seit einigen Jahren bekannt und deshalb noch als Werkzeug für schnelle und einfache Lösungen in Erinnerung. Tatsächlich eingesetzt hatte ich es allerdings noch nie, weshalb dies die Chance war es endlich einmal zu tun. Gesagt getan, runtergeladen und ausgeführt. Da Bottle allein auf der Standard-Library von Python basiert und mit Python 2.6+ wie auch Python 3.2+ kompatibel ist, funktionierte das sofort ohne Probleme. Und es hält was es verspricht!
Allein das erste Beispiel auf seiner Webseite zeigt bereits wie schnell ein Web-Server mit dynamischem Routing und Inhalten aufgesetzt wird:

from bottle import route, run, template
@route('/hello/<name>')
def index(name):
    return template('<b>Hello {{name}}</b>!', name=name)
run(host='localhost', port=8080)

Ja sogar Basic Authentication beherrscht es:

from bottle import route, run, template, auth_basic
def authenticate(username, password):
    return username == 'max' and password == 'mustermann'
@route('/hello/<name>')
@auth_basic(authenticate)
def index(name):
    return template('<b>Hello {{name}}</b>!', name=name)
run(host='localhost', port=8080)

Ist das nicht toll? Ich nehme stark an, dass da noch mehr geht, aber für den Moment bin ich vollauf zufrieden. 🙂

Johannes Meyer
Johannes Meyer
Developer

Johannes ist seit 2011 bei uns und hilft bei der Entwicklung zukünftiger Knüller (Icinga2, Icinga Web 2, ...) aus dem Hause NETWAYS.

DELL XPS13 – Ein zickiges Leichtgewicht mit großer Klappe

Nun war es endlich soweit. Nach Jahren als einer der wenigen die bei Meetings tatsächlich aufgepasst haben, erhielt Ich nun vor kurzem ein mobiles Arbeitsgerät. Das tolle dabei war, dass Ich mir selbst aussuchen durfte welches Modell, selbstverständlich in einem gewissen Rahmen. Einige Dinge waren von Anfang an klar: Es muss ein Ultrabook mit langer Akku-Laufzeit, Hellem Display mit naturgetreuen Farben, angenehmem Tipp-Verhalten und Tastatur-Beleuchtung sein.
Also zog Ich los und sah mich ein wenig um. Zur Wahl standen zwei Hersteller: Dell und Lenovo. Lenovo mit ihren ThinkPads war sofort der erste Anlaufpunkt. Nach einiger Lesarbeit landete Ich dann beim “ThinkPad X1 Carbon”. Was heraus stach war das IPS Panel (Sehr praktisch wenn man einmal nicht alleine am Gerät sitzt!) und ein nativer Ethernet Port. Nach noch mehr Lesarbeit im Netz war Ich jedoch vom Display, hinsichtlich der Helligkeit und Farbentreue, nicht mehr so beeindruckt. Dennoch schaffte es das X1 Carbon auf die Liste der Kandidaten.
Dann ging Ich zu Dell. Hier musste Ich nicht lange suchen, denn die XPS Modell-Reihe sticht im Ultrabook Segment geradezu heraus. Der Blickfang war selbstverständlich das “InfinityEdge” Display (“Cooool!”) und die daraus resultierende Größe des Gerätes. Ein 13″ Display in einem 11″ Gehäuse, wenn das nicht mal ein “Ultra”Book ist. Nach der gewohnten Lesarbeit war Ich noch mehr begeistert, denn das Display ist nicht nur groß, nein, es ist verdammt Hell, Kristallklar und diese Farben! Das einzige was Ich vermisste, war der native Ethernet Port. Doch ein 5Ghz Wifi und ein USB3.0 Port (mit dem richtigen Adapter) sorgte dafür, dass das XPS das X1 Carbon von der Kandidaten-Liste verdrängte.
Doch schon während meiner Recherchen im Netz fielen die ersten Fragen auf. Denn das XPS gibt es mit einem QHD+ und FHD Display. Aufgrund meiner geringen Erfahrung mit höher auflösenden Displays als FHD tendierte Ich eher zu eben jenem, denn im Netz war die Rede von Problemen bei der Skalierung in einzelnen Applikationen. Die Betriebssysteme selbst schnitten gut in den Erfahrungen anderer ab, ganz besonders Ubuntu 14.04+ und Windows 8+, doch einzelne Applikationen hätten angeblich mit starken Problemen wie zu kleinen Icons o.ä. zu kämpfen. Auch die Hardware des XPS machte bei diversen Besitzern Probleme, wie etwa das hypersensible Trackpad oder die zu Lags neigende Tastatur. (Ein einzelner Tastendruck führte zu wiederholten Eingabe des Zeichens.) Doch gerade letzere Probleme wurden bereits zu diesem Zeitpunkt durch UEFI-Upgrades seitens Dell behoben.
Also wollte Ich natürlich das XPS, mit dem FHD Display. Dummerweise wollte Ich es genau zu diesem Zeitpunkt, als Dell die Produktion einfror und somit die Version mit dem FHD Display nicht mehr anbot. Das was mir dann angeboten wurde, war das mit dem QHD+ Display, zusammen mit der Information, man wisse noch nicht wann die FHD Version wieder verfügbar sein wird. Langer Rede kurzer Sinn, nun sitze Ich vor einem Dell XPS13 mit QHD+ Display.
Das was Ich zuvor im Netz erfuhr, hat sich (mit gemischten Gefühlen) zu 100% bewahrheitet. Das Display ist wirklich großartig und die Hardware Probleme waren nicht existent. Doch mit der Auflösung habe auch Ich zu kämpfen. Windows 10 liefert einen angenehmes Ergebnis, Ubuntu 14.04 auch, solange man keinen externen Bildschirm anschließt der eine kleinere Auflösung hat. Denn dann skaliert Ubuntu zwar alle Symbol-Leisten und System-Icons korrekt, nicht jedoch die Schrift. Das bedeutet, ist ein externer Monitor angeschlossen, sehe Ich auf dem XPS QHD+ Display Schrift in der selben Größe wie auf dem externen FHD Monitor. Da hilft es mir herzlich wenig, wenn Ich zwar den Pfad in dem Ich mich gerade im Terminal aufhalte in der Titelleiste lesen kann, aber nicht das was sich in diesem Verzeichnis befindet. Nicht für QHD+ ausgelegte Applikationen machen allerdings in Windows und Ubuntu Probleme, da hilft nur eine Lupe griffbereit zu haben, oder auf Alternativen auszuweichen. (z.b. Firefox statt Chrome)
Alles in Allem, zufrieden bin Ich trotzdem. Man gewöhnt sich an alles und mit ein wenig Affinität zum “basteln” lassen sich gewisse Dinge auch selbst lösen. Dennoch, würde Ich jedem der sich für das XPS (oder irgendein ähnliches Gerät mit mehr als FHD Auflösung) interessiert, von der QHD+ Version abraten. Das ist vermutlich dann “nur” noch ein Leichtgewicht mit großer Klappe.

Johannes Meyer
Johannes Meyer
Developer

Johannes ist seit 2011 bei uns und hilft bei der Entwicklung zukünftiger Knüller (Icinga2, Icinga Web 2, ...) aus dem Hause NETWAYS.

Icinga Web 2 – Du kommst hier net rein

Inzwischen wisst ihr wie man ein neues Icinga Web 2 Modul anlegt und welche Möglichkeiten euch für die Navigation innerhalb eines Icinga Web 2 Moduls offen stehen. Heute möchte ich euch nun vorstellen wie es möglich ist, den Zugriff darauf zu kontrollieren.
Eine kleiner Hinweis vorweg: Da wir im folgenden keine neuen Elemente im UI einfügen werden, müsst ihr leider auf eine bebilderte Führung verzichten und euch mit hartem Code zufrieden geben. Dafür gibt es am Ende dieses Eintrags einen tarball mit dem daraus resultierenden aktuellem Stand des “Hello World” Moduls.
(more…)

Johannes Meyer
Johannes Meyer
Developer

Johannes ist seit 2011 bei uns und hilft bei der Entwicklung zukünftiger Knüller (Icinga2, Icinga Web 2, ...) aus dem Hause NETWAYS.

Icinga Web 2 – Wohin denn so schnell?

Nachdem Alexander vor einiger Zeit so freundlich war und euch gezeigt hat, wie man ziemlich einfach ein neues Modul für Icinga Web 2 einrichtet, setze ich genau an dieser Stelle an und erkläre, wieder auf der Basis des Hello World Moduls, die Einrichtung der Navigation.
(more…)

Johannes Meyer
Johannes Meyer
Developer

Johannes ist seit 2011 bei uns und hilft bei der Entwicklung zukünftiger Knüller (Icinga2, Icinga Web 2, ...) aus dem Hause NETWAYS.

Icinga Web 2 – Das darf nicht jeder

Ich möchte heute auf die verschiedenen Möglichkeiten eingehen, in Icinga Web 2 zu steuern wer was sieht und machen darf. Gerade in Unternehmen mit vielen Mitarbeitern oder einem großen Kundenkreis ist dies von essentieller Bedeutung für die Antwort auf die Frage, ob man Icinga Web 2 produktiv einsetzen kann, oder nicht. Da wir uns nun langsam auf den ersten Release Candidate hinzu bewegen, soll dieser Eintrag auch dazu dienen, zu präsentieren was in dieser Hinsicht noch zu erwarten ist.

Das Gruppen-/Rollen-Konzept

Erst einmal etwas zur Grundlage. Wer bereits weiß was der Titel verheißt, darf gerne direkt zum nächsten Abschnitt springen. In Icinga Web 2 gibt es Benutzer (Nicht zu verwechseln mit Icinga’s Kontakten. Von Icinga Web 2’s Benutzern weiß nur Icinga Web 2 etwas!) die sich auf verschiedenen Wegen anmelden können. (Basic-Auth, Datenbank, LDAP, …) Wurde konfiguriert wie Gruppen bestimmten Benutzern zugeordnet werden (Datenbank, LDAP, …), wird Icinga Web 2 versuchen nach erfolgreicher Anmeldung eines Benutzers seine Gruppen-Zugehörigkeiten zu registrieren. Nun existieren alle notwendigen Informationen, die verfügbaren Rollen einem Benutzer zuzuordnen. Eine Rolle definiert die Berechtigungen und Einschränkungen die für bestimmte Bereiche in Icinga Web 2 anzuwenden sind.

Berechtigungen

Eine Berechtigung definiert thematisch wer was sieht und machen darf, nach dem Motto “alles oder nichts”. In Bezug auf Icinga Web 2 selbst (also die Applikation an sich), trifft das auf die Konfiguration zu. Ob ein Benutzer alles, nur die Rollen oder die Benutzer und auch die Gruppen konfigurieren darf, wird mittels bestimmter Berechtigungen kontrolliert. Auch das Monitoring Modul (das eigentliche Herz, welches mit Icinga kommuniziert) bietet die Möglichkeit Berechtigungen zu definieren. In diesem Fall allerdings trifft dies auf die Kommandos zu, ob ein Benutzer alles, nur Kommentare hinzufügen oder Acknowledgements senden und auch Downtimes definieren darf. (Diese Berechtigungen stehen nicht mit bestimmten Hosts oder Services in Verbindung, sondern gelten für alle gleichermaßen.)

Einschränkungen

Eine Einschränkung wird zusätzlich zu einer möglicherweise notwendigen Berechtigung angewendet und, wie der Name schon sagt, schränkt den eigentlichen Zugriff noch weiter ein.
Dies geschieht aktuell im Monitoring Modul für Hosts und Services und schränkt die Anzeige der eigentlichen Objekte und, mit dem Release Candidate, auch ihrer entsprechend verknüpften Daten (Events, Kommentare, …) ein. (Sobald der Release Candidate verfügbar ist, wird dies auf Host- und Service-Gruppen sowie alle möglichen Aliase und Customvariablen ausgedehnt. Ob auch eine automatische Verknüpfung eines Benutzers mit einem Kontakt erfolgen kann, ist noch nicht endgültig entschieden.)
In Bezug auf Customvariablen gibt es im Monitoring Modul eine Besonderheit: Es ist möglich den Zugriff auf bestimmte Customvariablen vollständig zu sperren, unabhängig einer Rolle. Dies ist meist sinnvoll, wenn dort sensitive Informationen wie Passwörter o.ä. existieren.

Die URL Filter-Syntax

Da die Definition einer Einschränkung für Hosts und Services aktuell mittels eines URL Filters (wie sie überall in Icinga Web 2 verwendet werden) geschieht und es in der entsprechenden Konfigurations-Ansicht keinerlei Hilfestellung hierfür gibt, zeige ich zum Abschluss wie so ein Filter aussehen kann. Findige Nutzer werden evtl. bereits auf die Idee gekommen sein, den Editor in den entsprechenden Listen-Ansichten zu verwenden. Denn dort ist es aktuell möglich, sich die gewünschten Filter einfach “zusammen zu klicken”. Hat man all seine gewünschten Filter angewendet, erscheint deren Repräsentation in der Address-Zeile des Browsers und kann von dort direkt übernommen werden:
/icingaweb2/monitoring/list/hosts?(hostgroup_name=customer1|hostgroup_name=customer2)&host_name=office-*
Hier kann man bereits den grundlegenden Aufbau erkennen. Es sind Verknüpfungen (OR = |, AND = &, NOT = !) und Vergleiche (EQUAL =, NOT EQUAL = !=, GREATER = >, LESS = <, GREATER OR EQUAL = >=, LESS OR EQUAL = <=) möglich. Möchte man mehrere Bedingungen zusammenfassen, setzt man sie in runde Klammern. Sollen nun nur noch Hosts der Hostgruppe "customer2" zutreffen, welche eine bestimmte Customvariable besitzen, (Eine Funktion die aktuell leider nur mit Icinga 1.x funktioniert, mit dem Release Candidate allerdings auch mit Icinga 2.x.) muss der Filter folgendermaßen angepasst werden: (hostgroup_name=customer1|(hostgroup_name=customer2&_host_support_level>=2))&host_name=office-*
Handelt es sich um einen Service, sieht die Notation für Customvariablen folgendermaßen aus: _service_variable_name

In diesem Sinne, wünsche ich euch ein fröhliches berechtigen und einschränken. Bis demnächst, wenn’s mal wieder etwas von Icinga Web 2’s pure awesomeness zu berichten gibt. 😀

Johannes Meyer
Johannes Meyer
Developer

Johannes ist seit 2011 bei uns und hilft bei der Entwicklung zukünftiger Knüller (Icinga2, Icinga Web 2, ...) aus dem Hause NETWAYS.

Icinga Web 2 – Das kann Jeder

Das letzte mal habe ich zur Internationalisierung in Icinga Web 2 ein wenig aus dem Nähkästchen geplaudert. Heute widme ich mich einem ähnlichen, allerdings ungleich weniger beachtetem Thema:

Barrierefreiheit

Gerade im Bereich Open Source ist es nicht selten, dass Software nicht oder erst weit nach dem erstmaligen produktiven Einsatz, angesichts dem immer weiter zunehmenden Interesse und der Integration benachteiligter Individuen, überarbeitet oder erweitert wird. Zumeist liegt dies am Entwicklungsmodell. Jemand benötigt etwas oder ist unzufrieden mit den bereits existierenden Lösungen, entwickelt seine eigene Lösung und macht diese der Öffentlichkeit zugänglich welche dann durch interessierte Nutzer erweitert werden kann. In der Mehrzahl solcher Gegebenheiten ist die Zahl der tatsächlichen Anwender meist nicht oder nur bedingt absehbar, weshalb die Barrierefreiheit nicht berücksichtigt wird.
In Projekten, die von großen Unternehmen entwickelt oder in Auftrag gegeben werden, besteht allerdings meist ein spezielles Interesse an diesem Thema. Das Produkt muss entweder aus Vertrieblichen Gründen oder aus vorgeschriebenen Unternehmens-Richtlinien vollständig Barrierefrei sein, bevor es verkauft bzw. produktiv eingesetzt werden darf. Da vor einiger Zeit ein großes deutsches Unternehmen an uns heran getreten ist, wird sich das Team Web die nächsten Wochen vermehrt damit beschäftigen, Icinga Web 2 bis nur finalen Version Barrierefrei zu gestalten.
Wir werden uns an zwei bestimmten Standards orientieren, sie jedoch nicht in Gänze erfüllen. Gerade der „WCAG“ Standard beschreibt sehr viele Anforderungen, dessen Aufwand sehr hoch, die Relevanz für Icinga Web 2 wir jedoch entweder zu gering oder noch nicht einschätzen können.
Web Content Accessibility Guidelines (WCAG) sowie Teile der ISO 9241
Diese beiden Standards beschreiben die Grundzüge der Barrierefreiheit in modernen Web-Applikationen sowie die Anforderungen an eine erfolgreiche Interaktion zwischen Mensch und Maschine:

  • Farben & Kontraste
  • Dialoge
  • Bedienung
  • Navigation
  • Lesbarkeit
  • Verständlichkeit

Accessible Rich Internet Applications Suite (ARIA)
Dieser Standard erweitert HTML, sodass Bildschrimleser fehlerfrei innerhalb der Web-Applikation navigieren können und erweiterte Funktionen die sonst nur mit der Maus zugänglich wären, auch über die Tastatur vollständig nutzbar zu machen.
Außerdem werden wir sicherstellen, HTML auch semantisch korrekt zu verwenden. Das allseits beliebte <div> steht somit ganz oben auf dem Prüfstand.
Am Ende werden viele Verbesserungen direkt in das Framework eingepflegt worden sein, doch alle Anpassungen, die Icinga Web 2 in seiner grafischen Funktionalität bzw. der Vielfalt der Bedien-Elemente beschränken, werden mittels eines dedizierten Moduls realisiert.
Sobald alles fertig ist, kann sich niemand mehr raus reden, er habe die vielen kritischen, tief roten Anzeigen übersehen. Die sieht doch selbst ein Blinder, im wahrsten Sinne des Wortes. 😀

Johannes Meyer
Johannes Meyer
Developer

Johannes ist seit 2011 bei uns und hilft bei der Entwicklung zukünftiger Knüller (Icinga2, Icinga Web 2, ...) aus dem Hause NETWAYS.

Icinga Web 2 – Das Versteht Jeder

Mit Icinga Web 2 halten unfassbar viele innovative Funktionen Einzug in die Welt der Überwachung mit Icinga, welche euch bei jedem Einsatz erneut überwältigt, demütig und (selbstredend) erfolgreich eure Arbeit erledigen lassen. Selbstverständlich wird dies zu einem großen Teil dem geschuldet sein, was Euch im Browser visuell präsentiert wird, doch auch die kleinen Dinge tragen zu einem sehr großen Teil dieser Lebenserfahrung bei.
Eines dieser kleinen Dinge möchte ich euch heute vorstellen. Die Internationalisierung (Auch als i18n und l10n bekannt) sorgt dafür, dass Icinga Web 2 in der für euch richtigen Sprache, Zeitzone sowie Zeit- und Datums-Darstellung erscheint. Vollautomatisch. Natürlich könnt ihr die Sprache und Zeitzone euren Wünschen nach permanent festlegen, unabhängig davon was euch Icinga Web 2 mit unwiderlegbarer Genauigkeit automatisch vorschlägt.
Erreicht wird dies mittels der folgenden Techniken:
Sprache
Sendet ein Browser den HTTP Accept-Language Header bei einem Request, besteht für Icinga Web 2 die Möglichkeit aus den präferierten Sprachen des Benutzers automatisch die passendste und verfügbare auszuwählen. Gibt es keine der gewünschten Sprachen, wird Englisch oder die in den Nutzer-Einstellungen definierte Sprache aktiviert. (Im Hintergrund nutzen wir gettext.)
Zeitzone
Da die Browser leider nicht von sich aus die aktuelle Zeitzone des Benutzers bei einem Request mitsenden, müssen wir hierfür auf eine eigene Lösung zurückgreifen. Nachdem JavaScript nach dem ersten Request geladen wurde, kann es bei folgenden die Zeitzone in den Header einpflegen. Da wir sowieso jeden einzelnen Request mit JavaScript abfangen, ist das kein allzu großes Problem. Ist JavaScript deaktiviert oder unfähig die Zeitzone zu registrieren, wird UTC (bzw. die für den Server konfigurierte Standard Zeitzone) oder die in den Nutzer-Einstellungen definierte Zeitzone aktiviert.
Formate
Das Format für die Darstellung der Zeit und eines Datums wird anhand der aktuellen Sprache festgestellt. Hierfür greifen wir auf das PHP Modul Intl zurück.
Unglücklicherweise besitzen auch wir nicht die nötigen Kenntnisse alle der mehr als 6000 bekannten Sprachen in Icinga Web 2 zu integrieren. Deshalb stehen euch zum bevorstehenden Release folgende Sprachen zur Verfügung:

  • Englisch
  • Deutsch
  • Portugiesisch

Mit genug Huldigungen und über die Maßen lobenden Worten, sind wir durchaus dazu bereit eure gettext Sprachkataloge als Ergänzung zu integrieren.
Und nun wünschen wir euch viel Spaß mit Icinga Web 2, den ihr mit Sicherheit haben werdet.
Und zum Abschluss für all jene die allzu ernst durch’s Leben schreiten: 😉

Johannes Meyer
Johannes Meyer
Developer

Johannes ist seit 2011 bei uns und hilft bei der Entwicklung zukünftiger Knüller (Icinga2, Icinga Web 2, ...) aus dem Hause NETWAYS.

PHP Array, Improved

Python kanns, Ruby kanns, Ja sogar Java kanns. Nur PHP nicht. Nun, das stimmt nicht so ganz, PHP kann es über Umwege doch. Wovon die Rede ist?

Objekte als Hashtabellen-Schlüssel verwenden

Wie der eine oder andere Anwender von PHP weiß, können assoziative Arrays nur Integer und Zeichenketten als Schlüssel verwenden. Das ist manchmal sehr schade und man muss auf andere Werkzeuge ausweichen, indem man sich z.B. mit array_unique() und ArrayAccess sowie Iterator selbst etwas zurecht schustert.
Es gibt allerdings auch eine relativ elegante Lösung für dieses Problem: Die SplObjectStorage Klasse
Mit dieser Klasse aus der PHP SPL ist es möglich eine Datenstruktur zu schaffen, die sich wie ein assoziatives Array verhält, zugleich jedoch auch Objekte als Schlüssel erlaubt. Ein kleines Beispiel:

 1, 'prop2' => 2);
$obj2 = (object) array('prop1' => 11, 'prop2' => 22);
$obj3 = (object) array('prop1' => 11, 'prop2' => 22);
$objStorage = new SplObjectStorage();
$objStorage[$obj1] = 3;
$objStorage[$obj2] = 33;
$objStorage->contains($obj1); // TRUE
$objStorage->contains($obj2); // TRUE
$objStorage->contains($obj3); // FALSE
echo $objStorage[$obj1]; // 3
echo $objStorage[$obj2]; // 33
echo $objStorage[$obj3]; // UnexpectedValueException

Zu beachten ist, dass man zwar über ein Exemplar der Klasse SplObjectStorage iterieren kann, mit der $x as $y => $z Syntax jedoch unerwartetes Verhalten auftritt. In diesem Beispiel ist nämlich nicht $y das Objekt, sondern $z. $y entspricht der internen Position des Iterators. Nutzt man hingegen die $x as $y Syntax, ist $y das Objekt und man muss über $x[$y] auf dessen Wert zugreifen.
Ich hoffe ich konnte einen hilfreichen, wenn auch kurzen Einblick in die Klasse SplObjectStorage bieten. Dies war jedoch wirklich nur ein kleiner Ausschnitt, mehr kann über die Dokumentation erfahren werden.

Johannes Meyer
Johannes Meyer
Developer

Johannes ist seit 2011 bei uns und hilft bei der Entwicklung zukünftiger Knüller (Icinga2, Icinga Web 2, ...) aus dem Hause NETWAYS.

PHP Arrays filtern, Improved

Jeder der schonmal mit PHP in Berührung kam kennt vermutlich array_filter. Dieses kleine Schmuckstück ist manchmal ganz praktisch, kann jedoch nicht mit assoziativen Arrays umgehen. Die PHP SPL bietet jedoch seit Version 5.1 eine nette Alternative: Den FilterIterator
(more…)

Johannes Meyer
Johannes Meyer
Developer

Johannes ist seit 2011 bei uns und hilft bei der Entwicklung zukünftiger Knüller (Icinga2, Icinga Web 2, ...) aus dem Hause NETWAYS.