From 63b103b2c65bc7109c887fa083702cd1a79cb5b0 Mon Sep 17 00:00:00 2001 From: ihatemodels Date: Sat, 24 Feb 2024 02:15:37 +0000 Subject: [PATCH] Update go to 1.22; README --- .github/workflows/ci.yml | 11 ++-- Dockerfile | 10 ++-- LICENSE | 2 +- Makefile | 8 +-- README.md | 84 +++++++++++++++++++++++++--- go.mod | 4 +- internal/collector/arp_table.go | 2 +- internal/collector/collector.go | 2 +- internal/collector/collector_test.go | 2 +- internal/collector/cron.go | 2 +- internal/collector/gateways.go | 2 +- internal/collector/interfaces.go | 2 +- internal/collector/openvpn.go | 2 +- internal/collector/protocol.go | 2 +- internal/collector/services.go | 2 +- internal/collector/unbound_dns.go | 2 +- main.go | 4 +- opnsense/client.go | 7 +++ 18 files changed, 112 insertions(+), 38 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b1d4d9..dbec177 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: '1.21' + go-version: '1.22' - name: Check out code uses: actions/checkout@v2 - name: "Run Linters" @@ -51,7 +51,7 @@ jobs: uses: docker/metadata-action@v4 with: images: | - st3ga/opnsense-exporter + ghcr.io/AthennaMind/opnsense-exporter tags: | type=semver,pattern={{version}} @@ -60,12 +60,13 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - - name: Login to Docker Hub + - name: Login to GHCR if: github.event_name != 'pull_request' uses: docker/login-action@v2 with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Release build id: release_build diff --git a/Dockerfile b/Dockerfile index 75d5e6f..8fdd56e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.21 as build +FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.22 as build ARG TARGETPLATFORM ARG BUILDPLATFORM @@ -6,7 +6,7 @@ ARG TARGETOS ARG TARGETARCH ARG Version -WORKDIR /go/src/github.com/st3ga/opnsense-exporter +WORKDIR /go/src/github.com/AthennaMind/opnsense-exporter COPY . . RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} CGO_ENABLED=0 \ @@ -17,11 +17,11 @@ RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} CGO_ENABLED=0 \ FROM --platform=${BUILDPLATFORM:-linux/amd64} gcr.io/distroless/static-debian12:latest -LABEL org.opencontainers.image.source=https://github.com/st3ga/opnsense-exporter +LABEL org.opencontainers.image.source=https://github.com/AthennaMind/opnsense-exporter LABEL org.opencontainers.image.version=${Version} -LABEL org.opencontainers.image.authors="the st3ga Authors admins@st3ga.com" +LABEL org.opencontainers.image.authors="the AthennaMind Authors admins@AthennaMind.com" LABEL org.opencontainers.image.title="opnsense-exporter" -LABEL org.opencontainers.image.description="Prometheus exporter for OPNsense metrics" +LABEL org.opencontainers.image.description="Prometheus exporter for OPNsense" COPY --from=build /usr/bin/opnsense-exporter / CMD ["/opnsense-exporter"] \ No newline at end of file diff --git a/LICENSE b/LICENSE index 4f16d02..d752a7b 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2023 the st3ga Authors + Copyright 2023 the AthennaMind Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Makefile b/Makefile index e47cb61..dbd9a92 100644 --- a/Makefile +++ b/Makefile @@ -18,13 +18,13 @@ local-run: --web.telemetry-path="/metrics" \ --web.listen-address=":8080" \ --runtime.gomaxprocs=4 \ - --exporter.instance-label="opnsense-eu1" \ + --exporter.instance-label="opnsense-local1" \ --exporter.disable-arp-table \ --exporter.disable-cron-table \ --opnsense.protocol="https" \ - --opnsense.address="ops.domain.com" \ - --opnsense.api-key="XXX" \ - --opnsense.api-secret="XXX" \ + --opnsense.address="${OPS_ADDRESS}" \ + --opnsense.api-key="${OPS_API_KEY}" \ + --opnsense.api-secret="${OPS_API_SECRET}" \ --web.disable-exporter-metrics \ test: diff --git a/README.md b/README.md index 81e4ad7..38ff238 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,62 @@ # OPNsense Prometheus Exporter -The OPNsense exporter enables you to monitor your OPNsense firewall from the API. +The missing OPNsense exporter for Prometheus `Still under heavy development. The full metrics list is not yet implemented.` ## Table of Contents -**[About](#about)** -**[OPNsense User Permissions](#opnsense-user-permissions)** -**[Usage](#usage)** -**[Configuration](#configuration)** - - **[SSL/TLS](#ssltls)** -**[Grafana Dashboard](#grafana-dashboard)** +- **[About](#about)** +- **[OPNsense User Permissions](#opnsense-user-permissions)** +- **[Development](#development)** +- **[Usage](#usage)** + - **[Docker](#docker)** + - **[Docker Compose](#docker-compose)** + - **[Systemd](#systemd)** + - **[K8s](#k8s)** +- **[Configuration](#configuration)** + - **[SSL/TLS](#ssltls)** + - **[All Options](#all-options)** +- **[Grafana Dashboard](#grafana-dashboard)** ## About -This exporter delivers an extensive range of OPNsense-specific metrics, sourced directly from the OPNsense API. Focusing specifically on OPNsense, this exporter provides metrics about OPNsense, the plugin ecosystem and the services running on the firewall. However, it's recommended to use it with `node_exporter`. You can combine the metrics from both exporters in Grafana and in your Alert System to create a dashboard that displays the full picture of your system. +Focusing specifically on OPNsense, this exporter provides metrics about OPNsense, the plugin ecosystem and the services running on the firewall. However, it's recommended to use it with `node_exporter`. You can combine the metrics from both exporters in Grafana and in your Alert System to create a dashboard that displays the full picture of your system. While the `node_exporter` must be installed on the firewall itself, this exporter can be installed on any machine that has network access to the OPNsense API. +## Development + +This guide is for osx and Linux. + +### Create API key and secret in OPNsense + +`SYSTEM>ACCESS>USERS>[user]>API KEYS` + +[OPNsense Documentation](https://docs.opnsense.org/development/how-tos/api.html#creating-keys) + +### Run the exporter locally + +```bash +OPS_ADDRESS="ops.example.com" OPS_API_KEY=your-api-key OPS_API_SECRET=your-api-secret make local-run +curl http://localhost:8080/metrics +``` + +### Before PR + +- Make sure to sync the vendor if the dependencies have changed. + +```bash +make sync-vendor +``` + +- Make sure to run the tests and linters. + +```bash +make test +make lint +``` + ## OPNsense user permissions **TODO** @@ -27,6 +65,34 @@ While the `node_exporter` must be installed on the firewall itself, this exporte **TODO** +### Docker + +To run the exporter using Docker, you can use the following command: + +```bash +docker run -p 8080:8080 ghcr.io/AthennaMind/opnsense-exporter:latest \ + /opnsense-exporter \ + --log.level=debug \ + --log.format=json \ + --opnsense.protocol=https \ + --opnsense.address=ops.example.com \ + --opnsense.api-key=your-api-key \ + --opnsense.api-secret=your-api-secret \ + --exporter.instance-label=opnsense-eu1 \ + --web.listen-address=:8080 +``` +### Docker Compose + +**TODO** + +### Systemd + +**TODO** + +### K8s + +**TODO** + ## Configuration To configure where your OPNsense API is located, you can use the following flags: @@ -54,7 +120,7 @@ You can disable the exporter metrics using the following flag: - `--web.disable-exporter-metrics` - Exclude metrics about the exporter itself (promhttp_*, process_*, go_*). Defaults to `false`. -Full list +### All Options ```bash Flags: diff --git a/go.mod b/go.mod index 746ccda..e170a6f 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ -module github.com/st3ga/opnsense-exporter +module github.com/AthennaMind/opnsense-exporter -go 1.21 +go 1.22 require ( github.com/alecthomas/kingpin/v2 v2.3.2 diff --git a/internal/collector/arp_table.go b/internal/collector/arp_table.go index 6dd9c70..de6897f 100644 --- a/internal/collector/arp_table.go +++ b/internal/collector/arp_table.go @@ -3,10 +3,10 @@ package collector import ( "fmt" + "github.com/AthennaMind/opnsense-exporter/opnsense" "github.com/go-kit/log" "github.com/go-kit/log/level" "github.com/prometheus/client_golang/prometheus" - "github.com/st3ga/opnsense-exporter/opnsense" ) type arpTableCollector struct { diff --git a/internal/collector/collector.go b/internal/collector/collector.go index 633239d..be22f44 100644 --- a/internal/collector/collector.go +++ b/internal/collector/collector.go @@ -8,8 +8,8 @@ import ( "github.com/go-kit/log" "github.com/go-kit/log/level" + "github.com/AthennaMind/opnsense-exporter/opnsense" "github.com/prometheus/client_golang/prometheus" - "github.com/st3ga/opnsense-exporter/opnsense" ) const namespace = "opnsense" diff --git a/internal/collector/collector_test.go b/internal/collector/collector_test.go index d8f81df..17b75ad 100644 --- a/internal/collector/collector_test.go +++ b/internal/collector/collector_test.go @@ -3,8 +3,8 @@ package collector import ( "testing" + "github.com/AthennaMind/opnsense-exporter/opnsense" "github.com/go-kit/log" - "github.com/st3ga/opnsense-exporter/opnsense" ) func TestWithoutArpCollector(t *testing.T) { diff --git a/internal/collector/cron.go b/internal/collector/cron.go index 4d4aba6..b12c1dd 100644 --- a/internal/collector/cron.go +++ b/internal/collector/cron.go @@ -1,10 +1,10 @@ package collector import ( + "github.com/AthennaMind/opnsense-exporter/opnsense" "github.com/go-kit/log" "github.com/go-kit/log/level" "github.com/prometheus/client_golang/prometheus" - "github.com/st3ga/opnsense-exporter/opnsense" ) type cronCollector struct { diff --git a/internal/collector/gateways.go b/internal/collector/gateways.go index cf780f9..5f7b504 100644 --- a/internal/collector/gateways.go +++ b/internal/collector/gateways.go @@ -1,9 +1,9 @@ package collector import ( + "github.com/AthennaMind/opnsense-exporter/opnsense" "github.com/go-kit/log" "github.com/prometheus/client_golang/prometheus" - "github.com/st3ga/opnsense-exporter/opnsense" ) type gatewaysCollector struct { diff --git a/internal/collector/interfaces.go b/internal/collector/interfaces.go index 1814ca7..4b94ad9 100644 --- a/internal/collector/interfaces.go +++ b/internal/collector/interfaces.go @@ -1,10 +1,10 @@ package collector import ( + "github.com/AthennaMind/opnsense-exporter/opnsense" "github.com/go-kit/log" "github.com/go-kit/log/level" "github.com/prometheus/client_golang/prometheus" - "github.com/st3ga/opnsense-exporter/opnsense" ) type interfacesCollector struct { diff --git a/internal/collector/openvpn.go b/internal/collector/openvpn.go index 341b0fe..3fdfbb4 100644 --- a/internal/collector/openvpn.go +++ b/internal/collector/openvpn.go @@ -1,10 +1,10 @@ package collector import ( + "github.com/AthennaMind/opnsense-exporter/opnsense" "github.com/go-kit/log" "github.com/go-kit/log/level" "github.com/prometheus/client_golang/prometheus" - "github.com/st3ga/opnsense-exporter/opnsense" ) type openVPNCollector struct { diff --git a/internal/collector/protocol.go b/internal/collector/protocol.go index f8c7c61..128f90f 100644 --- a/internal/collector/protocol.go +++ b/internal/collector/protocol.go @@ -1,10 +1,10 @@ package collector import ( + "github.com/AthennaMind/opnsense-exporter/opnsense" "github.com/go-kit/log" "github.com/go-kit/log/level" "github.com/prometheus/client_golang/prometheus" - "github.com/st3ga/opnsense-exporter/opnsense" ) type protocolCollector struct { diff --git a/internal/collector/services.go b/internal/collector/services.go index 63694c1..1f48a35 100644 --- a/internal/collector/services.go +++ b/internal/collector/services.go @@ -1,10 +1,10 @@ package collector import ( + "github.com/AthennaMind/opnsense-exporter/opnsense" "github.com/go-kit/log" "github.com/go-kit/log/level" "github.com/prometheus/client_golang/prometheus" - "github.com/st3ga/opnsense-exporter/opnsense" ) type servicesCollector struct { diff --git a/internal/collector/unbound_dns.go b/internal/collector/unbound_dns.go index f53aabb..09e55cc 100644 --- a/internal/collector/unbound_dns.go +++ b/internal/collector/unbound_dns.go @@ -1,10 +1,10 @@ package collector import ( + "github.com/AthennaMind/opnsense-exporter/opnsense" "github.com/go-kit/log" "github.com/go-kit/log/level" "github.com/prometheus/client_golang/prometheus" - "github.com/st3ga/opnsense-exporter/opnsense" ) type unboundDNSCollector struct { diff --git a/main.go b/main.go index c11fc21..48770bb 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,8 @@ import ( "runtime" "syscall" + "github.com/AthennaMind/opnsense-exporter/internal/collector" + "github.com/AthennaMind/opnsense-exporter/opnsense" "github.com/alecthomas/kingpin/v2" "github.com/go-kit/log/level" "github.com/prometheus/client_golang/prometheus" @@ -16,8 +18,6 @@ import ( "github.com/prometheus/common/promlog" "github.com/prometheus/exporter-toolkit/web" "github.com/prometheus/exporter-toolkit/web/kingpinflag" - "github.com/st3ga/opnsense-exporter/internal/collector" - "github.com/st3ga/opnsense-exporter/opnsense" ) var version = "" diff --git a/opnsense/client.go b/opnsense/client.go index b680f83..9e47131 100644 --- a/opnsense/client.go +++ b/opnsense/client.go @@ -156,6 +156,13 @@ func (c *Client) do(method string, path EndpointPath, body io.Reader, responseSt switch resp.Header.Get("Content-Encoding") { case "gzip": reader, err = gzip.NewReader(resp.Body) + if err != nil { + return &APICallError{ + Endpoint: string(path), + Message: fmt.Sprintf("failed to decompress gzip response body: %s", err.Error()), + StatusCode: resp.StatusCode, + } + } default: reader = resp.Body }