diff --git a/inventory/group_vars/ffmwu-monitoring b/inventory/group_vars/ffmwu-monitoring
index da70e13..5216c26 100644
--- a/inventory/group_vars/ffmwu-monitoring
+++ b/inventory/group_vars/ffmwu-monitoring
@@ -6,6 +6,7 @@ common_repos:
backend-scripts:
repo_url: https://github.com/freifunk-mwu/backend-scripts.git
version: ansible
+ force: no
prometheus_conf_main: prometheus/prometheus.yml.j2
prometheus_opts: "--web.listen-address=localhost:9090"
diff --git a/roles/service-nginx-meshviewer/handlers/main.yml b/roles/service-nginx-meshviewer/handlers/main.yml
new file mode 100644
index 0000000..1aec9c3
--- /dev/null
+++ b/roles/service-nginx-meshviewer/handlers/main.yml
@@ -0,0 +1,5 @@
+---
+- name: restart nginx
+ systemd:
+ name: nginx
+ state: restarted
diff --git a/roles/service-nginx-meshviewer/meta/main.yml b/roles/service-nginx-meshviewer/meta/main.yml
new file mode 100644
index 0000000..ed4bbd8
--- /dev/null
+++ b/roles/service-nginx-meshviewer/meta/main.yml
@@ -0,0 +1,6 @@
+---
+dependencies:
+ - { role: nodejs }
+ - { role: yarn }
+ - { role: service-nginx }
+ - { role: service-yanic }
diff --git a/roles/service-nginx-meshviewer/tasks/main.yml b/roles/service-nginx-meshviewer/tasks/main.yml
new file mode 100644
index 0000000..aac90ec
--- /dev/null
+++ b/roles/service-nginx-meshviewer/tasks/main.yml
@@ -0,0 +1,47 @@
+---
+- name: create deploy directory
+ file:
+ path: "{{ meshviewer_path }}"
+ state: directory
+ mode: 0755
+ owner: www-data
+ group: www-data
+
+- name: clone repo
+ git:
+ repo: "https://github.com/ffrgb/meshviewer.git"
+ dest: "{{ meshviewer_src }}"
+ version: develop
+ force: yes
+
+- name: install dependencies
+ yarn:
+ path: "{{ meshviewer_src }}"
+
+- name: create meshviewer config
+ template:
+ src: config.js.j2
+ dest: "{{ meshviewer_src }}/config.js"
+ mode: 0644
+ owner: admin
+ group: admin
+
+- name: build
+ shell: yarn run gulp
+ args:
+ chdir: "{{ meshviewer_src }}"
+
+- name: deploy
+ shell: 'rm -rf {{ meshviewer_path }}/* && cp -ar build/* {{ meshviewer_path }} && chown www-data:www-data -R {{ meshviewer_path }}'
+ args:
+ chdir: "{{ meshviewer_src }}"
+ warn: no
+
+- name: write vhost
+ template:
+ src: meshviewer_vhost.conf.j2
+ dest: /etc/nginx/conf.d/meshviewer.conf
+ owner: root
+ group: root
+ mode: 0644
+ notify: restart nginx
diff --git a/roles/service-nginx-meshviewer/templates/config.js.j2 b/roles/service-nginx-meshviewer/templates/config.js.j2
new file mode 100644
index 0000000..756b652
--- /dev/null
+++ b/roles/service-nginx-meshviewer/templates/config.js.j2
@@ -0,0 +1,97 @@
+module.exports = function () {
+ return {
+ // Variables are NODE_ID and NODE_NAME (only a-z0-9\- other chars are replaced with _)
+ 'nodeInfos': [
+ {
+ 'name': 'Clients',
+ 'href': 'https://{{ http_grafana_prefix }}.{{ http_domain_external }}/dashboard/db/freifunk-mwu-knoten?panelId=1&var-NODE_ID={NODE_ID}&from=now-1d&fullscreen',
+ 'image': 'https://{{ http_grafana_prefix }}.{{ http_domain_external }}/render/dashboard-solo/db/freifunk-mwu-knoten?panelId=1&var-NODE_ID={NODE_ID}&from=now-1d&theme=light&width=650&height=350',
+ 'title': 'Knoten {NODE_ID} - weitere Statistiken'
+ },
+ {
+ 'name': 'Traffic',
+ 'href': 'https://{{ http_grafana_prefix }}.{{ http_domain_external }}/dashboard/db/freifunk-mwu-knoten?panelId=2&var-NODE_ID={NODE_ID}&from=now-1d&fullscreen',
+ 'image': 'https://{{ http_grafana_prefix }}.{{ http_domain_external }}/render/dashboard-solo/db/freifunk-mwu-knoten?panelId=2&var-NODE_ID={NODE_ID}&from=now-1d&theme=light&width=650&height=350',
+ 'title': 'Knoten {NODE_ID} - weitere Statistiken'
+ },
+ {
+ 'name': 'Load',
+ 'href': 'https://{{ http_grafana_prefix }}.{{ http_domain_external }}/dashboard/db/freifunk-mwu-knoten?panelId=3&var-NODE_ID={NODE_ID}&from=now-1d&fullscreen',
+ 'image': 'https://{{ http_grafana_prefix }}.{{ http_domain_external }}/render/dashboard-solo/db/freifunk-mwu-knoten?panelId=3&var-NODE_ID={NODE_ID}&from=now-1d&theme=light&width=650&height=350',
+ 'title': 'Knoten {NODE_ID} - weitere Statistiken'
+ },
+ {
+ 'name': 'Airtime',
+ 'href': 'https://{{ http_grafana_prefix }}.{{ http_domain_external }}/dashboard/db/freifunk-mwu-knoten?panelId=8&var-NODE_ID={NODE_ID}&from=now-1d&fullscreen',
+ 'image': 'https://{{ http_grafana_prefix }}.{{ http_domain_external }}/render/dashboard-solo/db/freifunk-mwu-knoten?panelId=8&var-NODE_ID={NODE_ID}&from=now-1d&theme=light&width=650&height=350',
+ 'title': 'Knoten {NODE_ID} - weitere Statistiken'
+ }
+ ],
+ 'globalInfos': [
+ {
+ 'name': 'Statistik - letzter Monat',
+ 'href': 'https://{{ http_grafana_prefix }}.{{ http_domain_external }}/d/000000001/freifunk-mwu-global?panelId=1&orgId=1&from=now-30d&to=now&var-INTERVAL=1d&fullscreen',
+ 'image': 'https://{{ http_grafana_prefix }}.{{ http_domain_external }}/render/d-solo/000000001/freifunk-mwu-global?panelId=1&orgId=1&from=now-30d&to=now&var-INTERVAL=1d&theme=light&width=650&height=350&tz=Europe%2FBerlin',
+ 'title': 'Statistik - letzter Monat'
+ },
+ {
+ 'name': 'Statistik - 6 Monate',
+ 'href': 'https://{{ http_grafana_prefix }}.{{ http_domain_external }}/d/000000001/freifunk-mwu-global?panelId=1&orgId=1&from=now-6M&to=now&var-INTERVAL=7d&fullscreen',
+ 'image': 'https://{{ http_grafana_prefix }}.{{ http_domain_external }}/render/d-solo/000000001/freifunk-mwu-global?panelId=1&orgId=1&from=now-6M&to=now&var-INTERVAL=7d&theme=light&width=650&height=350&tz=Europe%2FBerlin',
+ 'title': 'Statistik - 6 Monate'
+ },
+ {
+ 'name': 'Statistik - 1 Jahr',
+ 'href': 'https://{{ http_grafana_prefix }}.{{ http_domain_external }}/d/000000001/freifunk-mwu-global?panelId=1&orgId=1&from=now-1y&to=now&var-INTERVAL=14d&fullscreen',
+ 'image': 'https://{{ http_grafana_prefix }}.{{ http_domain_external }}/render/d-solo/000000001/freifunk-mwu-global?panelId=1&orgId=1&from=now-1y&to=now&var-INTERVAL=14d&theme=light&width=650&height=350&tz=Europe%2FBerlin',
+ 'title': 'Statistik - 1 Jahr'
+ }
+ ],
+ // String or array of data provider are supported
+ 'dataPath': [
+ '/data/'
+ ],
+ 'siteName': 'Freifunk in Mainz, Wiesbaden und Umgebung',
+ 'mapLayers': [
+{% for layer in map_layers %}
+ {
+ 'name': '{{ layer.name }}',
+ 'url': '{{ layer.url }}',
+ 'config': {
+ 'maxZoom': {{ layer.max_zoom }},
+ 'attribution': '{{ layer.attribution }}'
+ }
+ },
+{% endfor %}
+ ],
+ // Set a visible frame
+ 'fixedCenter': [
+ // Northwest
+ [
+ 50.165024,
+ 8.528137
+ ],
+ // Southeast
+ [
+ 49.895961,
+ 7.609406
+ ]
+ ],
+ 'siteNames': [
+{% for mesh in meshes %}
+ {
+ 'site': '{{ mesh.site_code }}',
+ 'name': '{{ mesh.site_name }}'
+ },
+{% if mesh.sites_virtual is defined %}
+{% for site, name in mesh.sites_virtual.items() %}
+ {
+ 'site': '{{ site }}',
+ 'name': '{{ name }}'
+ },
+{% endfor %}
+{% endif %}
+{% endfor %}
+ ]
+ };
+};
diff --git a/roles/service-nginx-meshviewer/templates/meshviewer_vhost.conf.j2 b/roles/service-nginx-meshviewer/templates/meshviewer_vhost.conf.j2
new file mode 100644
index 0000000..8aa0a63
--- /dev/null
+++ b/roles/service-nginx-meshviewer/templates/meshviewer_vhost.conf.j2
@@ -0,0 +1,78 @@
+proxy_cache_path /var/www/cache levels=1:2 keys_zone=osm_tiles:32m max_size=5G;
+proxy_temp_path /var/www/cache/tmp;
+
+upstream openstreetmap {
+ server a.tile.openstreetmap.org;
+ server b.tile.openstreetmap.org;
+ server c.tile.openstreetmap.org;
+}
+
+server {
+ listen 80;
+ listen [::]:80;
+ server_name {{ http_meshviewer_internal }} {{ http_meshviewer_external }};
+
+ include /etc/nginx/snippets/redirect-to-ssl.conf;
+ include /etc/nginx/snippets/letsencrypt-acme-challenge.conf;
+}
+
+server {
+ listen 443 ssl;
+ listen [::]:443 ssl;
+ server_name {{ http_meshviewer_internal }} {{ http_meshviewer_external }};
+
+ ssl_certificate /etc/nginx/ssl/{{ inventory_hostname_short }}.{{ http_domain_external }}/fullchain.pem;
+ ssl_certificate_key /etc/nginx/ssl/{{ inventory_hostname_short }}.{{ http_domain_external }}/privkey.pem;
+
+ include /etc/nginx/snippets/gzip.conf;
+ include /etc/nginx/snippets/letsencrypt-acme-challenge.conf;
+
+ root {{ meshviewer_path }};
+ index index.html index.htm;
+
+ location /data {
+ alias /var/lib/yanic/data;
+ }
+
+ location /tiles {
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X_FORWARDED_PROTO http;
+ proxy_set_header Host $http_host;
+ proxy_cache osm_tiles;
+ proxy_cache_valid 200 302 7d;
+ proxy_cache_valid 404 1m;
+ proxy_redirect off;
+ if (!-f $request_filename) {
+ rewrite ^/tiles(/.*)$ $1 break;
+ proxy_pass http://openstreetmap;
+ break;
+ }
+ }
+
+ location / {
+ try_files $uri $uri/ =404;
+ }
+}
+
+{% for mesh in meshes %}
+server {
+ listen 80;
+ listen [::]:80;
+ server_name {{ http_meshviewer_prefix }}.{{ mesh.http_domain_internal }} {{ http_meshviewer_prefix }}.{{ mesh.http_domain_external }};
+ return 301 https://{{ http_meshviewer_external }}$request_uri;
+
+ include /etc/nginx/snippets/letsencrypt-acme-challenge.conf;
+}
+
+server {
+ listen 443 ssl;
+ listen [::]:443 ssl;
+ server_name {{ http_meshviewer_prefix }}.{{ mesh.http_domain_internal }} {{ http_meshviewer_prefix }}.{{ mesh.http_domain_external }};
+ return 301 https://{{ http_meshviewer_external }}$request_uri;
+
+ include /etc/nginx/snippets/letsencrypt-acme-challenge.conf;
+}
+{% if not loop.last %}
+
+{% endif %}
+{% endfor %}
diff --git a/roles/service-nginx-meshviewer/vars/main.yml b/roles/service-nginx-meshviewer/vars/main.yml
new file mode 100644
index 0000000..34c31d0
--- /dev/null
+++ b/roles/service-nginx-meshviewer/vars/main.yml
@@ -0,0 +1,23 @@
+---
+http_meshviewer_external: "{{ http_meshviewer_prefix }}.{{ http_domain_external }}"
+http_meshviewer_internal: "{{ http_meshviewer_prefix }}.{{ http_domain_internal }}"
+
+meshviewer_path: "/var/www/{{ http_meshviewer_external }}"
+meshviewer_src: "/home/admin/clones/meshviewer"
+
+map_layers:
+ - osm_mapnik_cached:
+ name: 'OpenStreetMap.Mapnik CACHED'
+ url: 'https://{{ http_meshviewer_external }}/{z}/{x}/{y}.png'
+ max_zoom: 19
+ attribution: '© OpenStreetMap'
+ - osm_mapnik:
+ name: 'OpenStreetMap.Mapnik'
+ url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
+ max_zoom: 19
+ attribution: '© OpenStreetMap'
+ - osm_hot:
+ name: 'OpenStreetMap.HOT'
+ url: 'https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png'
+ max_zoom: 19
+ attribution: '© Openstreetmap France | © OpenStreetMap'