Skip to content

Add documentation for DHCP stats#3785

Merged
lunkwill42 merged 1 commit intoUninett:masterfrom
jorund1:dhcpstats-documentation
Feb 13, 2026
Merged

Add documentation for DHCP stats#3785
lunkwill42 merged 1 commit intoUninett:masterfrom
jorund1:dhcpstats-documentation

Conversation

@jorund1
Copy link
Copy Markdown
Collaborator

@jorund1 jorund1 commented Feb 12, 2026

Scope and purpose

Adds documentation to #3633

This pull request

  • Documents how to configure NAV to collect DHCP stats from Kea DHCPv4 servers
  • Documents how to configure NAV to collect DHCP stats from ISC DHCP servers
  • Documents how to migrate from old DHCP paths in graphite to new DHCP paths in graphite

Testing the migration steps outlined in this PR

This step-by-step assumes you're running containerized NAV and that you're fine with the Graphite/Carbon timeseries database being altered.

  1. Fill your Graphite/Carbon timeseries database with deprecated NAV 5.14 style DHCP paths.
    1.1. Copy this script to somewhere on your machine, e.g. ~/fill-graphite.bash. (It will fill Graphite with NAV 5.14 style DHCP paths.)

    #!/bin/sh
    
    cat <<EOF |
    4 example-1 admin 192.0.0.1 192.0.0.127 127 127 0 100000
    4 example-1 admin 192.0.0.129 192.0.0.255 127 127 0 100000
    4 example-1 admin 192.0.1.1 192.0.1.255 255 255 0 100000
    
    4 example-1 guest 192.0.2.0 192.0.2.255 256 256 0 10000
    4 example-1 guest 192.0.2.0 192.0.2.127 128 128 10001 50000
    4 example-1 guest 192.0.2.128 192.0.2.191 64 64 10001 50000
    4 example-1 guest 192.0.2.192 192.0.2.255 64 64 10001 50000
    
    6 example-1 admin 0:0:0:0:0:2:0:0 0:0:0:0:0:2:ffff:ffff 4294967296 100 0 100000
    6 example-1 guest 0:0:0:0:0:2:0:0 0:0:0:0:0:2:ffff:ffff 4294967296 100 0 100000
    EOF
    
    gawk '
    BEGIN {
      NOW = systime()
      srand(11)
      INTERVAL = 300
      DAYS = 30
    }
    
    NF == 9 {
      a = rand()
      b = rand()
      c = rand()
      _ = 1 / (a + b + c)
      a = a * _
      b = b * _
      c = c * _
      d = rand()*3.14*2
      e = 20 + rand()*8
      f = rand()
    
      ip_version = $1
      server_name = $2
      group_name = $3
      first_ip = $4; gsub(/[.:]/, "_", first_ip)
      last_ip = $5; gsub(/[.:]/, "_", last_ip)
      total_ips = $6
      upper_limit = $7
      start_offset = $8 * INTERVAL
      end_offset = $9 * INTERVAL
      noise = rand()
      for (offset = start_offset; offset < end_offset; offset += INTERVAL) {
        sine = (sin((offset*3.14*2)/(3600*e) + d)+1)/2
        noise = noise*f + rand()*(1-f)
        assigned_ips = int(sine*upper_limit*a+upper_limit*b+noise*upper_limit*c)
    
        printf("nav.dhcp.%d.pool.%s.%s.%s.%s.assigned %d %d\n", ip_version, server_name, group_name, first_ip, last_ip, assigned_ips, NOW - offset)
        printf("nav.dhcp.%d.pool.%s.%s.%s.%s.total %d %d\n", ip_version, server_name, group_name, first_ip, last_ip, total_ips, NOW - offset)
      }
    }' |
    
    socat - tcp:127.0.0.1:2003

    1.2. Run the script above inside your Graphite container, e.g.

     docker compose exec graphite rm -r /var/lib/graphite/whisper/nav/dhcp
     docker compose cp ~/fill-graphite.bash graphite:/run/fill-graphite.bash
     docker compose exec graphite bash /run/fill-graphite.bash
  2. Make sure you're on the same branch as Add functionality to graph DHCP stats on each VLAN page and Prefix page in NAV  #3633.

  3. In the NAV web UI, create the prefix 192.0.2.0/24 in seeddb and visit its page. Make sure there's no DHCP graphs there yet.

  4. Do the migration steps outlined in this PR, i.e.
    4.1. Copy this script to somewhere on your machine e.g. ~/migrate-graphite.bash

    #!/bin/bash
    
    # Renames the paths under nav.dhcp from the way paths are named in NAV
    # 5.14.x through NAV 5.16.x to the way paths are named in NAV 5.17.0 and
    # above
    
    # $WHISPER_ROOT should point to the root of the whisper database's file tree.
    # The user running this script must have write-access to this file tree.
    # You should take a backup of this file tree before running this script.
    WHISPER_ROOT="/var/lib/graphite/whisper"
    
    if ! [[ -d "$WHISPER_ROOT/nav/dhcp" ]]; then
        echo "Error: Could not find directory $WHISPER_ROOT/nav/dhcp" >&2
        echo "No paths to rename." >&2
        exit 2
    fi
    
    pushd "$WHISPER_ROOT" 1>/dev/null 2>/dev/null || exit 1
    for path in nav/dhcp/*/pool/*/*/*/*/*; do
        if ! [[ -f "$path" ]]; then
            continue
        fi
        if [[ -h "$path" ]]; then
            continue
        fi
        IFS='/' read -ra parts <<< "$path"
        ip_version="${parts[2]}"
        server_name="${parts[4]}"
        group_name="${parts[5]}"
        first_ip="${parts[6]}"
        last_ip="${parts[7]}"
        metric_name="${parts[8]}"
        if [[ "$group_name" = "pool-${first_ip}-${last_ip}" ]]; then
            new_path="nav/dhcp/servers/${server_name}/range/special_groups/standalone/${ip_version}/${first_ip}/${last_ip}/${metric_name}"
            new_dir="nav/dhcp/servers/${server_name}/range/special_groups/standalone/${ip_version}/${first_ip}/${last_ip}/"
        else
            new_path="nav/dhcp/servers/${server_name}/range/custom_groups/${group_name}/${ip_version}/${first_ip}/${last_ip}/${metric_name}"
            new_dir="nav/dhcp/servers/${server_name}/range/custom_groups/${group_name}/${ip_version}/${first_ip}/${last_ip}/"
        fi
        mkdir -p "$new_dir"
        if [[ -f "$new_path" ]]; then
            if whisper-fill "$path" "$new_path"; then
                # unlink "$path"  # Uncomment to unlink old path
                true
            fi
        else
            if ln --verbose "$path" "$new_path"; then
                # unlink "$path"  # Uncomment to unlink old path
                true
            fi
        fi
    done
    # find "nav/dhcp" -depth -empty -type d -delete  # Uncomment to remove any resulting empty directories
    popd 1>/dev/null 2>/dev/null || exit 1

    4.2. Run the script above inside your Graphite container, e.g.

     docker compose cp ~/migrate-graphite.bash graphite:/run/migrate-graphite.bash
     docker compose exec graphite bash /run/migrate-graphite.bash
  5. In the NAV web UI, reload the page for prefix 192.0.2.0/24. Now it should be DHCP graphs displayed there.

Contributor Checklist

  • Added a changelog fragment for towncrier
  • Added/amended tests for new/changed code
  • Added/changed documentation
  • Linted/formatted the code with ruff, easiest by using pre-commit
  • Wrote the commit message so that the first line continues the sentence "If applied, this commit will ...", starts with a capital letter, does not end with punctuation and is 50 characters or less long. See https://cbea.ms/git-commit/
  • Based this pull request on the correct upstream branch: For a patch/bugfix affecting the latest stable version, it should be based on that version's branch (<major>.<minor>.x). For a new feature or other additions, it should be based on master.
  • If applicable: Created new issues if this PR does not fix the issue completely/there is further work to be done
  • If it's not obvious from a linked issue, described how to interact with NAV in order for a reviewer to observe the effects of this change first-hand (commands, URLs, UI interactions)
  • If this results in changes in the UI: Added screenshots of the before and after
  • If this adds a new Python source code file: Added the boilerplate header to that file

@jorund1 jorund1 self-assigned this Feb 12, 2026
@jorund1 jorund1 added DHCP nonews No news fragment is necessary for this PR (e.g. refactoring, cleanups, workflow/development changes) labels Feb 12, 2026
@jorund1 jorund1 changed the title Add documentation for dhcpstats Add documentation for DHCP stats Feb 12, 2026
@jorund1
Copy link
Copy Markdown
Collaborator Author

jorund1 commented Feb 12, 2026

Marking as draft while I test the migration guide...

@jorund1 jorund1 marked this pull request as draft February 12, 2026 08:39
@jorund1 jorund1 marked this pull request as draft February 12, 2026 08:39
@codecov
Copy link
Copy Markdown

codecov bot commented Feb 12, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 63.32%. Comparing base (b45a062) to head (7fbd453).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #3785   +/-   ##
=======================================
  Coverage   63.32%   63.32%           
=======================================
  Files         619      619           
  Lines       45873    45873           
  Branches       43       43           
=======================================
  Hits        29051    29051           
  Misses      16812    16812           
  Partials       10       10           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jorund1
Copy link
Copy Markdown
Collaborator Author

jorund1 commented Feb 12, 2026

The last fixup commit removes documentation for ISC DHCP servers, since there is a chance this PR makes the NAV 5.17 window, but I don't see the branch that adds support for ISC DHCP servers making the NAV 5.17 window

Copy link
Copy Markdown
Member

@lunkwill42 lunkwill42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow, this is pretty comprehensive and nice - possibly one of the more detailed reference guides in the NAV docs 😄

It's good to see you have provided migration guides, even though I'm 99% sure that no one has set up DHCP stats collection in NAV while a GUI was missing 😉

I only have a few suggested changes, really...

Comment on lines +165 to +181
Updating the Crontab Entry
^^^^^^^^^^^^^^^^^^^^^^^^^^

Next, a cronjob for the program :program:`navdhcpstats` that runs periodically
every 5 minutes must be installed:

1. Save the following snippet in a file called :file:`navdhcpstats` in NAV's
:file:`etc/cron.d/` directory:

.. code-block:: console
:caption: etc/cron.d/navdhcpstats

*/5 * * * * navdhcpstats

2. Install the cronjob by running ``nav start navdhcpstats``.

.. _kea_dhcpv4_servers:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Realistically, 99.9% of users will not have to do anything here. New cron snippets are installed automatically when NAV is upgraded. Changed snippets will also overwrite old ones, unless you had made local changes.

If you are the rare flower that installs everything from source by hand, the upgrade guides will usually tell you to check for new or changed config files and make sure to add them.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😆 Ok, I suppose I can just remove this section, then?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed (didn't remove section but reworded)

@jorund1 jorund1 force-pushed the dhcpstats-documentation branch from 7738859 to fdf7c42 Compare February 12, 2026 12:17
Copy link
Copy Markdown
Member

@lunkwill42 lunkwill42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

@jorund1 jorund1 force-pushed the dhcpstats-documentation branch from fdf7c42 to 8a28bd6 Compare February 12, 2026 14:06
@jorund1
Copy link
Copy Markdown
Collaborator Author

jorund1 commented Feb 12, 2026

Have gone through Testing the migration steps outlined in this PR, and everything works as expected; marking this PR as ready.

@jorund1 jorund1 marked this pull request as ready for review February 12, 2026 14:13
@jorund1 jorund1 force-pushed the dhcpstats-documentation branch from 8a28bd6 to 417f8ce Compare February 13, 2026 08:58
@jorund1 jorund1 marked this pull request as draft February 13, 2026 08:59
@jorund1 jorund1 force-pushed the dhcpstats-documentation branch from 417f8ce to 3174831 Compare February 13, 2026 09:03
@jorund1 jorund1 marked this pull request as ready for review February 13, 2026 09:04
@jorund1
Copy link
Copy Markdown
Collaborator Author

jorund1 commented Feb 13, 2026

The second-last force-push was me just adding shopt -s nullglob to the migration script and accidentally including some local docker config, the last force-push was me removing the docker config again...

@jorund1 jorund1 force-pushed the dhcpstats-documentation branch from 3174831 to c55455c Compare February 13, 2026 09:16
@jorund1 jorund1 force-pushed the dhcpstats-documentation branch from c55455c to 7fbd453 Compare February 13, 2026 10:47
@sonarqubecloud
Copy link
Copy Markdown

@lunkwill42 lunkwill42 merged commit 33343e0 into Uninett:master Feb 13, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

DHCP nonews No news fragment is necessary for this PR (e.g. refactoring, cleanups, workflow/development changes)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants