Compare commits

...

3 commits

Author SHA1 Message Date
f52934cd25 friwall: don’t template settings
Let all settings including list of nodes be managed by application.
Exception is the list of networks instantiated from NetBox data.
2025-11-04 16:28:44 +01:00
ff90d3c0a3 debian: add wget to base packages 2025-11-04 16:17:33 +01:00
f3eec5fcbf collector: support custom poll intervals
Also simplify config context schema for SNMP since we only use a single
instance.
2025-11-04 15:23:15 +01:00
10 changed files with 31 additions and 58 deletions

View file

@ -1,18 +1,19 @@
Set up metric collection with prometheus and telegraf as the SNMP proxy. Set up metric collection with prometheus and telegraf as the SNMP proxy.
NetBox config context should contain the lists `prometheus_hosts` and `snmp_hosts` with job definitions. Each entry should define `name` and `nb_filter` user to query hosts from NetBox. For example: Each entry in `prometheus_config` should define `name`, `hosts` and optionally `interval`. As above, `hosts` is used as a query filter.
For SNMP the properties `snmp_hosts` and optional `snmp_interval` should define respectively the NetBox query filter and poll interval.
For example:
{ {
"prometheus_hosts": [ "prometheus_config": [
{ {
"name": "classroom", "name": "classroom",
"nb_filter": "role=desktop-computer status=active location=classroom" "hosts": "role=desktop-computer status=active location=classroom",
"interval": 300
} }
], ],
"snmp_hosts": [ "snmp_hosts": "role=switch name__isw=sw- status=active status=staged status=planned",
{ "snmp_interval": 300
"name": "switch",
"nb_filter": "role=switch name__isw=sw- status=active status=staged status=planned"
}
]
} }

View file

@ -28,7 +28,7 @@
template: template:
dest: "/etc/prometheus/conf.d/{{ item.name }}.yml" dest: "/etc/prometheus/conf.d/{{ item.name }}.yml"
src: "prometheus-job.yml.j2" src: "prometheus-job.yml.j2"
loop: "{{ prometheus_hosts }}" loop: "{{ prometheus_config }}"
loop_control: loop_control:
label: "{{ item.name }}" label: "{{ item.name }}"
notify: reload prometheus notify: reload prometheus

View file

@ -1,10 +1,14 @@
{% set devices = query("netbox.netbox.nb_lookup", "devices", api_filter="{{ item.nb_filter }}", raw_data=true) {% set devices = query("netbox.netbox.nb_lookup", "devices", api_filter="{{ item.hosts }}", raw_data=true)
| selectattr("primary_ip") | selectattr("primary_ip")
| map(attribute="name") | map(attribute="name")
| map("extract", hostvars) -%} | map("extract", hostvars) -%}
scrape_configs: scrape_configs:
- job_name: "{{ item.name }}" - job_name: "{{ item.name }}"
{% if item.interval is defined %}
scrape_interval: {{ item.interval }}s
scrape_timeout: {{ item.interval // 5 }}s
{% endif %}
relabel_configs: relabel_configs:
- source_labels: [__address__] - source_labels: [__address__]
regex: '([^.]+).*' regex: '([^.]+).*'

View file

@ -1,13 +1,13 @@
[[inputs.snmp]] [[inputs.snmp]]
interval = "300s" {% if snmp_interval is defined %}
interval = "{{ snmp_interval }}s"
{% endif %}
agent_host_tag = "source" agent_host_tag = "source"
agents = [ agents = [
{% for item in snmp_hosts %} {% for address in query("netbox.netbox.nb_lookup", "devices", api_filter=snmp_hosts, raw_data=true)
{% for address in query("netbox.netbox.nb_lookup", "devices", api_filter=item.nb_filter, raw_data=true)
| selectattr("primary_ip4") | map(attribute="primary_ip4.address") | selectattr("primary_ip4") | map(attribute="primary_ip4.address")
| ipaddr("address") %} | ipaddr("int") | sort | ipaddr("address") %}
"{{ address }}", "{{ address }}",
{% endfor %}
{% endfor %} {% endfor %}
] ]
version = 3 version = 3

View file

@ -39,8 +39,9 @@
- git - git
- ifupdown2 - ifupdown2
- rsync - rsync
- vim
- tmux - tmux
- vim
- wget
# for base Debian the main interfaces file is just an include # for base Debian the main interfaces file is just an include
- name: Remove interface definitions added by installer - name: Remove interface definitions added by installer

1
roles/friwall/README.md Normal file
View file

@ -0,0 +1 @@
Install and configure the [FRIwall](https://git.fri.uni-lj.si/rc/friwall) web application for managing firewall nodes. For settings and operation refer to that project.

View file

@ -38,17 +38,18 @@
extra_args: --user --break-system-packages --no-warn-script-location extra_args: --user --break-system-packages --no-warn-script-location
notify: restart uwsgi notify: restart uwsgi
- name: Configure base settings - name: Ensure setting files exist
template: copy:
dest: "/srv/friwall/{{ item }}" dest: "/srv/friwall/{{ item }}.json"
src: "{{ item }}.j2" content: |
{}
owner: friwall owner: friwall
group: friwall group: friwall
mode: 0600 mode: 0600
force: no force: no
loop: loop:
- nodes.json - nodes
- settings.json - settings
notify: restart uwsgi notify: restart uwsgi
- name: Configure list of networks - name: Configure list of networks

View file

@ -1,14 +0,0 @@
auto lo
iface lo inet loopback
{% for iface in interfaces %}
auto {{ iface.name }}
iface {{ iface.name }} inet static
{% for address in iface.ip_addresses %}
address {{ address.address }}
{% endfor %}
{% if iface.custom_fields.gateway %}
gateway {{ iface.custom_fields.gateway.address | ipaddr('address') }}
{% endif %}
{% endfor %}

View file

@ -1,11 +0,0 @@
{% set nodes = query('netbox.netbox.nb_lookup', 'devices', api_filter='role=firewall', raw_data=true)
| selectattr('config_context') | selectattr('config_context', 'contains', 'master')
| selectattr('config_context.master', '==', inventory_hostname)
| map(attribute='name') -%}
{
{% for node in nodes %}
"{{ hostvars[node] | device_address | selectattr('family.value', '==', 4)
| map(attribute='address') | ipaddr('address') | first }}": -1{{ '' if loop.last else ',' }}
{% endfor %}
}

View file

@ -1,10 +0,0 @@
{
"ldap_host": "{{ domain }}",
"ldap_user": "{{ password.ldap_user }}",
"ldap_pass": "{{ password.ldap_pass }}",
"ldap_base_dn": "{{ ldap_base_dn }}",
"oidc_server": "{{ password.oidc_server }}",
"oidc_client_id": "{{ password.oidc_client_id }}",
"oidc_client_secret": "{{ password.oidc_client_secret }}",
"wg_net": "{{ wg_net }}"
}