Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Dockerfile, compose.yaml, and an unbound example config #66

Merged
merged 6 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/integration.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
name: integration

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

jobs:
integration:
runs-on: [ubuntu-latest]
steps:
- name: Install Go
uses: actions/setup-go@v4
with:
go-version: "1.21.x"
- name: checkout
uses: actions/checkout@v4
- name: Start containers
run: docker compose up --build --detach
- name: run integration test
run: go test --tags=integration
- name: Stop containers
if: always()
run: docker compose down
20 changes: 20 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.21.4-bookworm AS build

WORKDIR /go/src/app

COPY go.mod .
COPY go.sum .

RUN go mod download

COPY *.go .

ENV CGO_ENABLED=0

RUN GOOS=$TARGETOS GOARCH=$TARGETPLATFORM go build -v -o /go/bin/unbound_exporter ./...

FROM gcr.io/distroless/static-debian12

COPY --from=build /go/bin/unbound_exporter /

ENTRYPOINT ["/unbound_exporter"]
21 changes: 21 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
services:
unbound_exporter:
build: .
command: [ "-unbound.host=unix:///var/run/socket/unbound.ctl" ]
volumes:
- socket:/var/run/socket:ro
ports:
- "9167:9167"
depends_on:
unbound:
condition: service_started
unbound:
image: "mvance/unbound:1.18.0"
volumes:
- socket:/var/run/socket:rw
- ./unbound-example.conf:/opt/unbound/etc/unbound/unbound.conf
ports:
- "1053:1053/udp"
- "1053:1053/tcp"
volumes:
socket:
52 changes: 52 additions & 0 deletions integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//go:build integration

package main

import (
"net/http"
"testing"

"github.com/prometheus/common/expfmt"
)

// TestIntegration checks that unbound_exporter is running, successfully
// scraping and exporting metrics.
//
// It assumes unbound_exporter is available on localhost:9167, and Unbound on
// localhost:1053, as is set up in the docker-compose.yml file.
//
// A typical invocation of this test would look like
//
// docker compose up --build -d
// go test --tags=integration
// docker compose down
func TestIntegration(t *testing.T) {
resp, err := http.Get("http://localhost:9167/metrics")
if err != nil {
t.Fatalf("Failed to fetch metrics from unbound_exporter: %v", err)
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
t.Fatalf("Expected a 200 OK from unbound_exporter, got: %v", resp.StatusCode)
}

parser := expfmt.TextParser{}
metrics, err := parser.TextToMetricFamilies(resp.Body)
if err != nil {
t.Fatalf("Failed to parse metrics from unbound_exporter: %v", err)
}

// unbound_up is 1 if we've successfully scraped metrics from it
unbound_up := metrics["unbound_up"].Metric[0].Gauge.GetValue()
if unbound_up != 1 {
t.Errorf("Expected unbound_up to be 1, not: %v", unbound_up)
}

// Check some expected metrics are present
for _, metric := range []string{"go_info", "unbound_queries_total", "unbound_response_time_seconds", "unbound_cache_hits_total"} {
if _, ok := metrics[metric]; !ok {
t.Errorf("Expected metric is missing: %s", metric)
}
}
}
84 changes: 84 additions & 0 deletions unbound-example.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
## This is an example Unbound configuration file
## This is needed to use unbound_exporter
remote-control:
control-enable: yes
control-interface: /var/run/socket/unbound.ctl

# The rest of this file is standard Unbound configuration
# There's nothing special here.
server:
cache-max-ttl: 86400
cache-min-ttl: 300
directory: "/opt/unbound/etc/unbound"
do-ip4: yes
do-ip6: no
do-tcp: yes
do-udp: yes
edns-buffer-size: 1232
interface: 0.0.0.0
port: 1053
prefer-ip6: no
rrset-roundrobin: yes
username: "_unbound"
log-local-actions: no
log-queries: no
log-replies: no
log-servfail: yes
logfile: /opt/unbound/etc/unbound/unbound.log
verbosity: 2
infra-cache-slabs: 4
incoming-num-tcp: 10
key-cache-slabs: 4
msg-cache-size: 142768128
msg-cache-slabs: 4
num-queries-per-thread: 4096
num-threads: 3
outgoing-range: 8192
rrset-cache-size: 285536256
rrset-cache-slabs: 4
minimal-responses: yes
prefetch: yes
prefetch-key: yes
serve-expired: yes
so-reuseport: yes
aggressive-nsec: yes
delay-close: 10000
do-daemonize: no
do-not-query-localhost: no
neg-cache-size: 4M
qname-minimisation: yes
access-control: 127.0.0.1/32 allow
access-control: 192.168.0.0/16 allow
access-control: 172.16.0.0/12 allow
access-control: 10.0.0.0/8 allow
access-control: fc00::/7 allow
access-control: ::1/128 allow
auto-trust-anchor-file: "var/root.key"
chroot: ""
deny-any: yes
harden-algo-downgrade: yes
harden-below-nxdomain: yes
harden-dnssec-stripped: yes
harden-glue: yes
harden-large-queries: yes
harden-referral-path: no
harden-short-bufsize: yes
hide-http-user-agent: no
hide-identity: yes
hide-version: yes
http-user-agent: "DNS"
identity: "DNS"
private-address: 10.0.0.0/8
private-address: 172.16.0.0/12
private-address: 192.168.0.0/16
private-address: 169.254.0.0/16
private-address: fd00::/8
private-address: fe80::/10
private-address: ::ffff:0:0/96
ratelimit: 1000
tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
unwanted-reply-threshold: 10000
use-caps-for-id: yes
val-clean-additional: yes
include: /opt/unbound/etc/unbound/a-records.conf
include: /opt/unbound/etc/unbound/srv-records.conf
Loading