Seite wählen

NETWAYS Blog

Divide and Conquer – Verteilte Git-Konfiguration

In meinem zehnten Monat als Consultant bei NETWAYS angekommen, bin ich inzwischen gut in verschiedenste Kundenprojekte integriert. Das sorgt einerseits für einen abwechslungsreichen Alltag mit immer neuen Herausforderungen, andererseits stellte sich irgendwann ein grundlegendes Problem heraus: Ich kann nicht jonglieren!

Dabei wäre das bei der Vielzahl an geschäftlichen Email-Adressen, SSH- und GPG-Schlüsseln und anderen Kleinigkeiten, die sich von Kunde zu Kunde, Plattform zu Plattform und Projekt zu Projekt unterscheiden, dringend notwendig. Ein unsignierter Commit mit falscher Email auf Github, Gitlab oder sonstiger Plattform ist da bei meinem Talent für Schusseligkeit nur eine Frage der Zeit. Glücklicherweise gibt es ein Git-Feature, das hier unterstützen kann: Die hierarchische Einbindung mehrerer .gitconfig Dateien.

Theorie und Möglichkeiten

Standardmäßig liest git die hinterlegte Konfiguration laut offizieller Dokumentation aus vier Verzeichnissen/Dateien aus:

  • $(prefix)/etc/gitconfig – der systemweiten Git-Konfiguration
  • $XDG_CONFIG_HOME – einer userspezifischen Git-Konfiguration, oftmals unter $HOME/.config/git
  • ~/.gitconfig – einer weiteren userspezifischen Git-Konfiguration, auch „globale Git-Konfiguration“ genannt
  • $GIT_DIR/config – einer Git-Konfiguration auf Repositoryebene

Die Dateien werden hierbei von jeder Routine, die auf git-Konfiguration zurückgreift, in obiger Reihenfolge ausgelesen, bei mehrfach definierten Werten greift hierbei der letzte, sodass ein „Feintuning“ von globaler Konfiguration hin zu projektspezifischen Einstellungen im Repository schon einmal möglich ist. Für noch bessere Verteilung und optionale Einbindung von erweiternder Konfiguration gibt Git Dir eine praktische Direktive an die Hand: includeIf.

Sie erlaubt es Dir, optional Konfiguration von beliebigen Stellen in die gerade betrachtete Datei einzubinden – die dort hinterlegten Einstellungen werden also zeitgleich evaluiert. Für eine bessere Kontrolle darüber, wann zusätzliche Einstellungen importiert werden sollen, können wir uns erneut die Dokumentation von git, genauer gesagt den Abschnitt zu Conditional Includes anschauen, denn hier gibt es verschiedene Optionen:

  • gitdir – die Einbindung erfolgt, wenn die Auswertung (via Befehl, Script, etc.) der Git-Konfiguration aus einem der Angabe entsprechenden (Unter-)Verzeichnis erfolgt. gitdir unterstützt Wildcards und Case(in)sensitivity.
  • onbranch – die Einbindung erfolgt aus einem momentan ausgecheckten Branch erfolgt, der der Angabe entspricht. Wildcards und Case(in)sensitivity werden auch hier unterstützt
  • hasconfig:remote.*.url – die Schreibweise ist etwas gewöhnungsbedürftig und auch die Anwendungsmöglichkeiten nicht so geradlinig wie bei den anderen Optionen: Hierbei werden optional Einstellungen eingebunden, wenn sich irgendwo in der lokalen Git-Konfiguration (nicht zwingend in der gleichen betrachteten Datei) eine remote URL findet, die der Angabe entspricht. Das ist bspw. nützlich, um mehrere Repositories mit bestimmter, immer gleicher Konfiguration zu versehen  (z.B. alle Repositories, die Icingaweb2-Module bereitstellen)

Praxis

Doch wie kann so etwas in der Praxis aussehen? Wie eingangs erwähnt, war mir vor Allem die Handhabe mehrerer kundenbezogener Email-Adressen und damit verknüpfter GPG-Schlüssel zu lästig, sodass ich hier für die Konfiguration zu einem hierarchischen Ansatz zurückgriff. Meine globale Git-Konfiguration unter ~/.gitconfig gestaltete ich also wie folgt:

Screenshot einer globalen Gitkonfiguration

Globale Gitkonfiguration unter ~/.gitconfig

Neben „Standardeinstellungen“ wie meinem im Commit zu setzenden Namen, der Defaultbranch bei der Erstellung neuer Repositories, die Anweisung, Commits immer mittels GPG zu signieren und das dafür zu nutzende Programm finden sich hier vier includeIf-Abschnitte.

Diese decken die verschiedenen Unterverzeichnisse meines Entwicklungsverzeichnisses ~/repositories/ ab – die trailing Slashes am Ende der jeweiligen Pfaddefinition sorgen dafür, dass die jeweiligen Unterverzeichnisse rekursiv gematcht werden. Im Beispiel hieße das, dass sowohl ein Repository unter ~/repositories/netways/blogpost_dbodky als auch ein Repository unter ~/repositories/netways/icinga-related/director-patches die zusätzlichen Git-Einstellungen unter ~/repositories/netways/.gitconfig einbinden würde.

In den in meiner globalen Git-Konfiguration referenzierten optional einzubindenden Dateien finden sich dann die Kunden- oder projektspezifischen Einstellungen für Git – das können mal mehr, mal weniger sein, um das Beispiel einfach zu halten hier die minimalistische Version für meine privaten Repositories, in der ich nur meine private Emailadresse sowie den damit verknüpften GPG-Schlüssel für die Signierung angebe:

Screenshot einer spezifischen Gitkonfiguration unter ~/repositories/private/.gitconfig

Spezifische Gitkonfiguration unter ~/repositories/private/.gitconfig

Was ihr jetzt in eure Gitkonfigurationen einbauen möchtet und wie ihr sie strukturiert, ist komplett euch überlassen – Git macht hierbei keine Vorschriften sondern arbeitet stur die vier eingangs erwähnten Dateien und alle optional einzubindenden Verzeichnisse und Dateien ab. Wichtig ist lediglich die Reihenfolge der Angaben, da sich diese gegebenenfalls überschreiben können.

Falls Du diesen Blogpost interessant fandest, aber bei Git noch Steigerungsbedarf siehst oder bei der Erwähnung von remote URLs ausgestiegen bist, kann ich Dir an dieser Stelle die NETWAYS Gitlab Schulung ans Herz legen, wo Du in Sachen Versionsverwaltung und DevOps voll durchstarten kannst.

Daniel Bodky
Daniel Bodky
Platform Advocate

Daniel kam nach Abschluss seines Studiums im Oktober 2021 zu NETWAYS und beriet zwei Jahre lang Kunden zu den Themen Icinga2 und Kubernetes, bevor es ihn weiter zu Managed Services zog. Seitdem redet und schreibt er viel über cloud-native Technologien und ihre spannenden Anwendungsfälle und gibt sein Bestes, um Neues und Interessantes rund um Kubernetes zu vermitteln. Nebenher schreibt er in seiner Freizeit kleinere Tools für verschiedenste Einsatzgebiete, nimmt öfters mal ein Buch in die Hand oder widmet sich seinem viel zu großen Berg Lego. In der wärmeren Jahreszeit findet man ihn außerdem oft auf dem Fahrrad oder beim Wandern.

SSL leicht gemacht – forcierte Weiterleitung von HTTP auf HTTPS einrichten


In den vorherigen Teilen der Serie wurde bereits die Erstellung und Einbindung der Zertifikate beschrieben. Eines Tages wünscht sich der Admin jedoch die sichere Verbindung aller Seitenbesucher, ohne dass diese manuell ein https voranstellen müssen. Gerade bei einer Migration einer bestehenden Seite wird der
Parallelbetrieb erst nach eingehenden Tests eingestellt und das SSL jeweils forciert, um Seitenbesucher nicht mit ungültigen Zertifikaten oder Mixed Content zu verunsichern.
Die eigentliche Umsetzung ist dann relativ einfach und wird in unserem Beispiel direkt in der Vhost-Definition des Apache vorgenommen. Übrigens, die verfügbaren Vhosts sind zu finden unter: /etc/apache2/sites-available. Hier wird nun der HTTP-Vhost (Port 80) um den unten aufgezeigten Block mit den Rewrites erweitert.

<VirtualHost *:80>
  ServerAdmin webmaster@netways.de
  ServerName www.netways.de
  DocumentRoot /var/www/html/netways.de/
  <Directory /var/www/html/netways.de/>
   Options FollowSymLinks
   AllowOverride All
  </Directory>
  ErrorLog /var/log/apache2/error.log
  LogLevel warn
  CustomLog /var/log/apache2/access.log combined
  RewriteEngine on
  RewriteCond %{SERVER_NAME} =www.netways.de [OR]
  RewriteCond %{SERVER_NAME} =netways.de
  RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
 </VirtualHost>

Damit das Ganze nun auch funktioniert, muss natürlich der SSL-Vhost unter Port 443 erreichbar sein. Wie dieser initial erstellt wird, ist im Artikel SSL-Zertifikat einbinden beschrieben.
Übrigens: wer Let’s Encrypt verwendet, wird im Wizard gleich gefragt, ob SSL forciert werden soll. Der Wizard übernimmt dann die oben gezeigten Schritte. Wie man Let’s Encrypt einsetzt, haben wir natürlich auch schon einmal beschrieben. Damit später keine Seitenbesucher verloren gehen, sollte der HTTP-Vhost, der auf Port 80 läuft, nicht abgeschaltet werden. Die Verbindung ist mit dieser Maßnahme sicher und alle Besucher werden auf https umgeleitet.
Wer damit gar nichts zu tun haben will, und trotzdem stets auf der sicheren Seite sein will, der kann natürlich seine Seite auch bei NETWAYS im Managed Hosting betreuen lassen. Hier kümmern wir uns darum.
In den anderen (teilweise noch kommenden) Blogposts zum Thema SSL leicht gemacht geht es um:

Icinga 2 Plugin Check Command Definitionen beisteuern

Auswahl_154Icinga 2 liefert eigene CheckCommand Objektkonfiguration mit, welche den Start in die neue Konfigurationswelt durchaus erleichtert – einfach z.B. ping4 als check_command Attribut für die Service-Apply-Regel verwenden, und fertig. Auf den ersten Blick sind dies hier lediglich die (gängigsten) Definitionen aus dem Monitoring-Plugins-Projekt – allerdings wurden über die letzten Monate viele neue Definitionen aus der Community Patches eingereicht. Dabei ist aufgefallen, dass der ultimative Guide hierfür noch nicht geschrieben ist.
Warum sollte man diese Definition Upstream einschicken?

  • Es ist Open Source – jeder kann diese verwenden und aktualisieren/verbessern
  • Eine zentrale Stelle für Konfiguration und Dokumentation
  • Entwickler können Updates einspielen und mit Best Practices unterstützend zur Seite stehen
  • In einem verteilten Setup müssen die Definitionen nicht (manuell) verteilt werden, sondern werden durch Upstream-Pakete ausgeliefert

Ich habe hierzu im Icinga Wiki einen detaillierten Guide verfasst – auf gehts, gemeinsam schaffen wir das! 🙂
PS: Unsere Kollegen setzen dies auch in Kundenprojekten vor Ort um, und schicken diese Patches dann an uns Entwickler 🙂

LConf 1.5.0 released

lconf_logoWhile the backend exporter has been overhauled in many places, we’ve also tackled long lasting issues such as missing schema attributes or nasty import bugs. On the other hand, the LConf web interface reflects the schema additions as well fixes annoying bugs with custom variable removal, and also integrates community contributed patches such as a parent host drop down.
Download LConf Backend 1.5.0, LConf Icinga Web 1.5.0 & LConf Standalone Web 1.5.0.
Find the Changelog below.
Cheers, Alex & Michael

LConf Backend 1.5.0

CHANGES

  • Schema: Additional object attributes (see below) requiring update
  • Import: Skip already existing objects, set address to host name if not defined

FEATURES

  • Feature #1432: add inherits_parent attribute for host/service dependency
  • Feature #1480: add first_notification_delay as schema attribute to host/service
  • Feature #1886: contact attributes address1-6 missing
  • Feature #2082: Add ldap_person and allow auxiliary objectClass in ldap schema
  • Feature #2429: Add the attribute „address6“ for ipv6 dual stack to the host-settings
  • Feature #2495: Add attribute contactgroup_members and servicegroup_members
  • Feature #2690: Complete LDAP schema
  • Feature #2889: LConfImport: Skip already existing objects and continue import
  • Feature #2891: LConfImport: Set host address to name if not existing

FIXES

  • Bug #2192: LConfImport.pl doesn’t ignore comments in objects.cache
  • Bug #2240: hostgroup alias/display_name is overridden with cn
  • Bug #2761: Escalations are no longer exported
  • Bug #2857: LConf 1.5.0-rc1: additional hostgroups are exported with a „+“
  • Bug #2859: Default User filter for Icinga2 is too restrictive
  • Bug #2887: str2arr_by_delim_without_excludes() must not return empty array values
  • Bug #2899: customvars with value 0 are not exported

LConf Icinga Web Module 1.5.0

CHANGES

  • Requires LConf Backend 1.5.x!
  • New object attributes (see below)
  • Export checks for unsaved settings
  • Exclude not supported attributes in properties tab

FEATURES

  • Feature #1568: Notify to save last changes before export
  • Feature #1727: Parent settings for Hosts via GUI
  • Feature #2096: connection manager: add the default 389 port and localhost as default
  • Feature #2425: Add „Max check attempts“ to check settings
  • Feature #2517: ServiceEscalationServiceGroups and ServiceEscalationHostGroups dropdown missing
  • Feature #2645: Add an option to define override or add for specific attribute values (groups, contacts, etc)
  • Feature #2875: Add attributes: host address6, {contact,service}group_members, contact address1-6
  • Feature #2877: Add inherits_parents (dependencies 1.x) and first_notification_delay (host/service) attributes

FIXES

  • Bug #2177: Quicklinks from grid to access the hostObject directly in LConf don’t work
  • Bug #2410: delete customvar not possible
  • Bug #2553: Testcheck fails at expanding macros
  • Bug #2643: Contacts can not have an interval
  • Bug #2811: Find a way to hide StructObj attributes in Properties tab
  • Bug #2839: Add property not possible

LConf Standalone Web 1.5.0

Same as Icinga Web Module, and additionally:
FEATURES

  • Feature #2841: Increase Ajax timeout
  • Feature #2871: Add support for Apache 2.4

Release packages for RPM repository configuration

While writing and updating training material for our Icinga 2 courseware, we are also re-evaluating the installation and configuration process by practical example and learning curve. Certain parts of the Icinga2 documentation are updated similar to the training material from training participants feedback and also by the trainers themselves.
In this special example, we found it tremendously hard to install the icinga rpm repository from packages.icinga.org inside the CentOS 7 training VM. By default you would just type a long string to fetch the yum repository information.

# wget https://packages.icinga.com -O /etc/yum.repos.d/ICINGA-release.repo
# yum makecache

training_install_icinga_repositoryWhile this works pretty well for release repositories, how about the snapshot repository for testing bleeding edge stuff? Similar to EPEL release package we’d just want that for Icinga as well.
The RPM package called ‚icinga-rpm-release‘ contains the repository’s GPG key as well as the yum configuration for the release repository which is enabled by default. The snapshot repository is installed, but disabled. You may use it with the „–enablerepo“ yum parameter.
Example for el7:

Name:           icinga-rpm-release
Version:        7
Release:        1%{?dist}
Summary:        Icinga Package Repository
Group:          System Environment/Base
License:        GPLv2
URL:            https://packages.icinga.com
Source0:        %{name}-%{version}.tar.gz
Source1:        https://packages.icinga.com
Source2:        https://packages.icinga.com
Source3:        https://packages.icinga.com
BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildArch:      noarch
Requires:       redhat-release >=  %{version}
%description
This package contains the Icinga package repository GPG key
as well as configuration for yum.
%prep
%setup -q -c -T
install -pm 644 %{SOURCE0} .
%build
%install
rm -rf $RPM_BUILD_ROOT
#GPG key
install -Dpm 644 %{SOURCE1} $RPM_BUILD_ROOT%{_sysconfdir}/pki/rpm-gpg/RPM-GPG-KEY-ICINGA
#yum
install -dm 755 $RPM_BUILD_ROOT%{_sysconfdir}/yum.repos.d
install -pm 644 %{SOURCE2} %{SOURCE3} $RPM_BUILD_ROOT%{_sysconfdir}/yum.repos.d
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root,-)
%config(noreplace) /etc/yum.repos.d/*
/etc/pki/rpm-gpg/*
%changelog

All distribution releases are organized in git branches, which keeps it fairly simply for Jenkins package builds.
Tip: Downloading the url-referenced sources („SourceX: Url“) works using spectool.

$ cd sources
$ spectool -g ../icinga-rpm-release.spec
modify, add, commit

In the end, you’ll get a nice rpm which installs just fine. No need to worry about the GPG key or where to store the configuration files.

# rpm -i https://packages.icinga.com
# yum search icinga2

See you in the icinga2 training sessions!