Fastd mit ansible-ffms: Howto?

Es gibt einen Check if == „00“ then domaene = „Test“ (sinngemäß) irgendwo, bin ich bei „ubuntufizieren“ im Sommer drüber gestolpert :wink: Mit dem damaligen Gerüst tut das (für l2tp zumindest), vgl. ansible-4830/host_vars/l2tp-ams01 at master · ffgtso/ansible-4830 · GitHub und hier:

 Domäne-00   : 10.255.128.2 / 2001:bf7:1310:666::2
 Domäne-01   : 10.234.128.2 / 2001:bf7:1310:128::2
 Domäne-02   : 10.234.160.2 / 2001:bf7:1310:160::2
 Domäne-03   : 10.234.176.2 / 2001:bf7:1310:176::2
 Domäne-04   : 10.234.144.2 / 2001:bf7:1310:144::2
 Domäne-05   : 10.234.192.2 / 2001:bf7:170:192::2
 Domäne-06   : 10.234.64.2 / 2001:bf7:170:64::2
Last login: Wed Nov  6 12:39:07 2019 from 178.201.40.162
root@l2tp-ham01 ~ # 

(„00“ ist als Auffangmesh geplant, daher finde ich die Nummer so schön passend ;))

Ja, daß daraus das letzte Oktett der jew. IP-Adresse wird, habe ich gesehen; aber Ansible meckert ja nicht über den Inhalt, sondern das fehlen der Variable:

"AnsibleUndefinedVariable: 'dict object' has no attribute 'server_id'"

Und das verstehe ich nicht. (Und auch nicht, warum es 2x „server_id“ gibt und wie sich das, falls überhaupt, vererbt. Und wenn unterschiedlicher Zweck, fände ich eine unterschiedliche Benamsung übersichtlicher; schätze man, das ist ›historisch so gewachsen‹?)

Die server_id in der Domänenliste bestimmt das wie vielte Gateway in einer Domäne es sein soll. Darüber wird z. B. die IP in der Domäne festgelegt, die dann für die Knoten als Gateway dient.

Die server_id in host_vars ist deprecated. Sie wird noch an ein zwei Stellen verwendet, wurde aber durch vm_id ersetzt. Hintergrund ist, dass wir früher pro Domäne eine eigene VM hatten. Als wir dann Multidomänengateways eingeführt haben, ist die server_id pro Domäne definiert worden und die vm_id für übergeordnete Sachen, die pro VM gelten, eingeführt worden.

Danke für die Erläuterung!

Eine der Stellen ist dann wohl die, die mich grade kirre macht?

collectd/templates/collectd.conf.j2:
------------------------------------
{% if "domaenenliste" in hostvars[host] %}
	Host "{{domaenen[domaene[0]].ffv4_network | ipaddr(hostvars[host].domaenenliste[domaene[0]].server_id) | ipaddr('address') }}"
{% else %}
	Host "{{domaenen[domaene[0]].ffv4_network | ipaddr(hostvars[host].server_id) | ipaddr('address') }}"
{% endif %}

Ich verstehe das so, daß bei Vorhandensein von domaenenliste: die server_id: von dort genommen wird, ansonsten die äußere.

Das müßte auch der Abschnitt sein, der mir noch immer dies beschert:

TASK [collectd : deploy collectd.conf] ******************************************************************************************
fatal: [fastd-fra01]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'dict object' has no attribute 'server_id'"}

Nun hat host_vars/fastd-fra01 aber beide server_id:-Einträge — hat irgendwer 'ne Idee, warum Ansible trotzdem ins Essen bricht?

Okay, hier ist irgendwas fischig :frowning:

Auch beim Bau der Karte fliegt mir Ansible um die Ohren :frowning:

 TASK [mapserver_interfaces : Create interfaces - batman file] ***************************************************************
fatal: [newmap]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: Unable to look up a name or access an attribute in template string (# {{ ansible_managed }}\n\n{% set indexer = [0] -%}\n{% for domaene in domaenen|dictsort %}\n\n{% set group = \"gateways\" -%}\n{% if \"domaene-\"+domaene[0] in groups -%}\n{% set group = \"domaene-\"+domaene[0] -%}\n{% endif -%}\n\n# BEGIN: Domäne-{{domaene[0]}}\n{% if indexer.append(indexer.pop() + 1) %}{% endif %}{# increment indexer by 1 #}\n# BATMAN Interface für Domäne-{{domaene[0]}}\nauto bat{{domaene[0]}}\niface bat{{domaene[0]}} inet6 static\n        address fe80::dcad:beff:feef:{{ '%02x' % indexer[0] }}{{'%02d' % server_id}}\n        netmask 64\n        pre-up modprobe batman-adv\n\tpre-up ip link add bat{{domaene[0]}} type batadv\n\tpost-up ip link set address de:ad:be:ef:{{ '%02x' % indexer[0] }}:{{server_id}} dev bat{{domaene[0]}}\n        post-up ip link set dev bat{{domaene[0]}} up\n        post-up batctl -m bat{{domaene[0]}} it 10000\n{% for host in groups[group] %}\n{% if group == \"gateways\" %}\n{% if domaene[0] in hostvars[host].domaenenliste %}\n\tpost-up batctl -m bat{{domaene[0]}} if add t{{domaene[0]}}-{{ host }} ||:\n{% endif %}\n{% else %}\n        post-up batctl -m bat{{domaene[0]}} if add tap-{{ host }} ||:\n{% endif %}\n{% endfor %}\n        post-up batctl -m bat{{domaene[0]}} mm 0\n\tpost-up ip -6 addr add {{domaene[1].ffv6_network | ipaddr(server_id) | ipaddr('address')}}/64 dev bat{{domaene[0]}}\n\tpost-up pgrep -a -x -f \"batadv-vis -i bat{{domaene[0]}}.*\" || batadv-vis -i bat{{domaene[0]}} -u /run/batadvvis.{{domaene[0]}}.sock -s >/dev/null 2>&1&\n        pre-down pkill -x -f \"batadv-vis -i bat{{domaene[0]}}.*\" ||:\n\niface bat{{domaene[0]}} inet static\n        address {{domaene[1].ffv4_network | ipaddr(server_id) | ipaddr('address') }}\n        netmask {{domaene[1].ffv4_network | ipaddr('netmask')}}\n        post-down ip link del bat{{domaene[0]}}\n\n# Tunnel-Interfaces für Domäne-{{domaene[0]}}\n{% for host in groups[group] %}\n{% if group == \"gateways\" %}\n{% if domaene[0] in hostvars[host].domaenenliste %}\n{% if indexer.append(indexer.pop() + 1) %}{% endif %}{# increment indexer by 1 #}\nauto t{{domaene[0]}}-{{ host }}\niface t{{domaene[0]}}-{{ host }} inet manual\n{% if build_tunnels_over_ipv6_if_available is defined and build_tunnels_over_ipv6_if_available and ipv6 is defined and hostvars[host].ipv6 is defined %}\n        pre-up ip link add $IFACE type ip6gretap local {{ipv6}} remote {{hostvars[host].ipv6}} dev {{ansible_default_ipv6.interface}} key {{domaene[0]|int}}\n{% else %}\n        pre-up ip link add $IFACE type gretap local {{ansible_default_ipv4.address}} remote {{hostvars[host].ipv4}} dev {{ansible_default_ipv4.interface}} key {{domaene[0]|int}}\n{% endif %}\n        pre-up ip link set dev $IFACE address de:ad:be:ef:{{ '%02x' % indexer[0] }}:{{server_id}}\n        pre-up ip link set $IFACE up\n        post-up batctl -m bat{{domaene[0]}} if add $IFACE ||:\n        pre-down batctl -m bat{{domaene[0]}} if del $IFACE ||:\n        post-down ip link del $IFACE\n\n{% endif %}\n{% else %}\n{% if indexer.append(indexer.pop() + 1) %}{% endif %}{# increment indexer by 1 #}\nauto tap-{{ host }}\niface tap-{{ host }} inet manual\n        pre-up ip link add $IFACE type gretap local {{ansible_default_ipv4.address}} remote {{hostvars[host].ansible_ssh_host}} dev {{ansible_default_ipv4.interface}} \n        pre-up ip link set dev $IFACE address de:ad:be:ef:{{ '%02x' % indexer[0] }}:{{server_id}}\n        pre-up ip link set $IFACE up\n        post-up batctl -m bat{{domaene[0]}} if add $IFACE ||:\n        pre-down batctl -m bat{{domaene[0]}} if del $IFACE ||:\n        post-down ip link del $IFACE\n\n{% endif %}\n{% endfor %}\n# END: Domäne-{{domaene[0]}}\n\n{% endfor %} \n\n).\nMake sure your variable name does not contain invalid characters like '-': %d format: a number is required, not StrictUndefined"}

„AnsibleUndefinedVariable: Unable to look up a name or access an attribute in template string […] Make sure your variable name does not contain invalid characters like ‚-‘: %d format: a number is required, not StrictUndefined“ — hilfreiche Fehlermeldungen sehen anders aus :frowning: Gibt’s einen Debug-/Interativ-Modus in Ansible, indem man sehen kann, was genau da fehlt (ich verstehe „StrictUndefined“ als „da fehlt einer Variable der Inhalt“)?

Ich hab’ dann mal spaßeshaber Euer Setup 1:1 auf eine neue VM zu deployen versucht — das lief über diese fragliche Stelle ganz fluffig hinweg …

TASK [mapserver_interfaces : Create interfaces - batman file] *******************************************************************
ok: [karte]

… bis es dann an die Zertifikate geht :wink:

Lt. grep sind die partner:-Einträge (die ich weggelassen habe bei den Gateways) für Ansible nicht relevant — was übersehe ich?

Ich hab da mal aufgeräumt… Vlt. hilft das ja schon…

Ich taste mich gerade von der anderen Seite heran; mapserver deployed schon mal (https://mskarte.4830.org/), gateways streikt noch: wir setzen auf ISC, Ihr habt wohl nur noch Kea auf dem Schirm :wink:

TASK [collectd : deploy kea.py] *************************************************************************************************
task path: /root/test-ansible-ffms.git/roles/collectd/tasks/main.yml:83
[…]
fatal: [fastd-gut01]: FAILED! => {
    "changed": false, 
    "msg": "AnsibleUndefinedVariable: 'kea' is undefined"
}

when: collectd.collect_dhcp and domaenenliste is defined ist da etwas zu wenig abgefragt :wink: PR kommt dann gesammelt.

2 „Gefällt mir“

Korrekt. Mangels Testkandidaten fällt das manchmal hinten über.

Danke dir.

Sagt mal, dies protocol static static_domaene{{domaene[0]}} { in bird6.conf.j2, soll das für FFRL/FFNW-Upstream sein? Macht irgendwie sonst keinen Sinn, /56er-Routen zu erzeugen, oder was übersehen ich?

V6 läuft bei uns derzeit nur über den FFRL, weil wir unser PI-V6 noch nicht richtig in Betrieb haben. Das steht auch noch auf das langen langen Aufgabenliste.

Du hast fast die Frage beantwortet :slight_smile: Der FFRL routet IIRC bis auf /56 runter, daher würde es Sinn machen, /56er Routen aus den /64ern zu machen, die in den Meshes konfiguriert werden. @stefan6, wie haltet Ihr das, nähmt Ihr auch /64er?

Hintergrund der Frage: wir (FFGT) sind ja auch mit eigenem AS unterwegs, wir routen intern auf /64er runter, daher sind im Ansible aus beliebigen /64ern erzeugte /56 kontraproduktiv. Ich würde daher dies entsprechend in if defined FFRL…" -Abfragen packen, oder eine neue Variable, Upstream_v6_min_prefix oder so, einführen.

Hi,

ja, bei uns geht auch /64 :wink:

1 „Gefällt mir“

Beim FFRL geht meines Wissens nach auch /64, aber nur eine gewisse Anzahl, ein paar Hundert oder so.

Dann stellt sich die Frage, warum Ihr die Domänen-/64 (oder was immer da angegeben wird vom Nutzer — was anderes als ein /64 macht für SLAAC aber keinen Sinn) in bird6.conf.j2 auf /56 erweitert? Weiß das noch wer? :slight_smile:

Ja, weil der FFRL früher keine /64 angenommen hat. :stuck_out_tongue:

Ok :slight_smile:

Zum Kartenserver hab’ ich auch 'ne Frage: wir haben Ortskürzel als Site-/Domänenidentifizierung, also „gut“, „rhw“, „wrz“ und so, Ihr, soweit ich das sehe, „ffmsd01“, „ffmsd60“ usw. Ihr konfiguriert per Ansible den Hopglass-Server so, daß er auf allen Tunneln zu den Domänen lauscht und dann greift Ihr über Rewrite-Regeln im Nginx auf z. B. $server:4000/nodes.json?…&site=d01 zu, sehe ich das richtig?

Eine echte Trennung der Datensammlung auf Mesh-Ebene ist das aber nicht? Wenn ich in Domäne d01 einen Knoten mit Kennung d60 laufen ließe (Config-Änderung auf dem Knoten), würde der auf der Karte in Domäne 60 auftauchen, oder? Dafür rennt nur ein Hopglass-Server, statt ein Datensammler pro Domäne/Mesh …

Kurz gesagt: Ja. :slight_smile:

btw. man möchte nicht 70x Hopglass-Server haben auf dem Karten Server. Das hab ich ausprobiert und für scheiße befunden. Vor allem weil die VM sich beim Booten so schnell zerledert das man die Instanzen auch nicht mehr beendet bekommt… :see_no_evil:

Man kann natürlich den Sammeldienst / Hopglass-Server auf den Gateways laufen lassen. Hat aber dann das Problem das man ${AnzahlGatewaysInDomäne} Endpunkte per Domain in das Frontend einbinden muss und keinen Punkt mehr hat wo man Zentral Knotendaten hat. Doof für Freifunk API, freifunk-karte.de oder was auch immer…

Yo, macht Sinn. Hab’s etwas umgebaut für uns, da wir mit Strings arbeiten und nicht dXX; ist halt eine Rewrite-Rule je Domäne, aber es gibt komplexere Nginx-Configs :slight_smile: Außerdem können die Daten auch von $Woanders kommen, so können wir auf newmap.4830.org auch die Daten von den Yanics des alten Setups anzeigen (andere batman-Version) :heart:. Ich mach’ die Tage mal 'nen PR.

PR ist raus:

Ein paar Erweiterungen der Rollen:

  • BREAKING CHANGE: über ipv6backbone64prefixstr muß nun der interne v6-Präfix für Tunnel gesetzt werden — 2a03:2260:115:ffa1:: sollte nur FFMS nutzen.
  • BREAKING CHANGE: Port 25 wird vom Mesh gen Internet blockiert.
  • BREAKING CHANGE: Um ‚zone „{{freifunk.kurzname}}.“‘ weiterhin konfiguriert zu bekommen, muß „have_local_kurzname_zone“ gesetzt werden. (Wir nutzen 4830.org als freifunk.kurzname, und damit erzeugt die Rolle eine falsche Version der öffentlichen Domain. Zudem tun „private“ TLDs in aktuellen, insbesondere mobilen, Browsern eher so mäßig — mit DoH wird’s auch haarig.)
  • ospf_nat_ip kann analog ff*_nat_ip verwendet werden, um diese IP im internen Routing per OSPF bekannt zu machen.
  • gateways_l2tp_slovenija nutzt letzten python2-kompatiblem commit vor der Änderung auf python3-only.
  • Es gibt eine „FFGT-Version“ des Mapservers, welche statt numerische Domains zu erzwingen mit normalen Textbezeichnern umgehen kann, ferner können dem Hopglass auch externe Quelle zugeführt werden.
  • Bei ipv6_direkt_ausleiten wird ein zusätzlicher OSPF-Prozeß gestartet, der die lokalen Netze dem internen Routing bekannt macht, sodaß auch der Rückweg klappt.
  • Kleinere Fixes.
1 „Gefällt mir“

Neue Frage: wie wird Graphite befüllt? Bei meinen Knoten bleiben die statistischen Daten irgendwie auf der Strecke, z. B. bei https://newmap.4830.org/map01/#!v:m;n:8c3badd95829 :frowning: Yanic pustet die Daten ja auf Wunsch in eine InfluxDB, aber Hopglass-Server kann das AFAICS nicht (hat dafür einen Prometheus-Endpunkt)?