Skip to content

Commit 20bcefd

Browse files
committed
Also initial commit
1 parent ea4347a commit 20bcefd

File tree

15 files changed

+989
-1
lines changed

15 files changed

+989
-1
lines changed

.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Ignore random backed up files
2+
*.bak
3+
4+
# Don't commit build artifacts
5+
out/
6+
7+
# Ignore vim buffer files
8+
*.swp
9+
*.swo
10+
11+
# Ignore stray configuration files
12+
config.json
13+
config.yaml
14+
config.toml

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
BSD 2-Clause License
22

3-
Copyright (c) 2023, XXX
3+
Copyright (c) 2026, Leon Fernandez
44

55
Redistribution and use in source and binary forms, with or without
66
modification, are permitted provided that the following conditions are met:

Makefile

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
NAME:=observation-encoder
2+
3+
#######################################
4+
# VERSION SOURCE OF TRUTH FOR PROJECT #
5+
#######################################
6+
VERSION:=0.0.0
7+
8+
OUT:=./out
9+
DEFAULT_INSTALLDIR:=/usr/bin
10+
INSTALL:=install -p -m 0755
11+
COMMIT:=$$(cat COMMIT 2> /dev/null || git describe --dirty=+WiP --always 2> /dev/null)
12+
13+
.PHONY: build install clean fmt vet coverage
14+
15+
16+
all: build
17+
18+
build: outdir
19+
go build -v -ldflags "-X 'main.version=$(VERSION)' -X 'main.commit=$(COMMIT)'" -o $(OUT)/ ./cmd/...
20+
21+
outdir:
22+
-mkdir -p $(OUT)
23+
24+
clean:
25+
-rm -rf $(OUT)
26+
27+
install:
28+
test -z "$(DESTDIR)" && $(INSTALL) $(OUT)/$(PROG) $(DEFAULT_INSTALLDIR) || $(INSTALL) $(OUT)/$(PROG) $(DESTDIR)$(prefix)/bin/
29+
30+
test:
31+
go test ./...
32+
33+
coverage: outdir
34+
go test -coverprofile=$(OUT)/coverage.out ./...
35+
go tool cover -html="$(OUT)/coverage.out" -o $(OUT)/coverage.html
36+
37+
fmt:
38+
go fmt ./...
39+
40+
vet:
41+
go vet ./...
42+
43+
tarball: outdir
44+
@test ! -f COMMIT || (echo "Trying to make tarball from extracted tarball?" && false)
45+
@test ! -z $(COMMIT) || (echo "Not tracked by git?" && false)
46+
@test -z $$(git status --porcelain) || (echo "won't make tarball from dirty history" && false)
47+
echo "$(COMMIT)" > $(OUT)/COMMIT
48+
git archive --format=tar.gz --prefix=$(NAME)/ -o $(OUT)/$(NAME)-$(VERSION).tar.gz --add-file $(OUT)/COMMIT HEAD
49+
cd $(OUT) && sha256sum -b $(NAME)-$(VERSION).tar.gz > $(NAME)-$(VERSION).sha256.txt

README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Build
2+
3+
```
4+
make
5+
```
6+
7+
# Install
8+
9+
```
10+
sudo make install
11+
```
12+
13+
# Run
14+
15+
```
16+
observation-encoder -config /path/to/config/file
17+
```
18+
19+
# Sample config file
20+
21+
```json
22+
{
23+
"address": "127.0.0.1",
24+
"port": "10000",
25+
"cert":
26+
{
27+
"interval": 100,
28+
"cert_dir": "/path/to/certificates/dir"
29+
},
30+
"api":
31+
{
32+
"active": true,
33+
"address": "127.0.0.1",
34+
"port": "10001"
35+
}
36+
}
37+
```

cmd/observation-encoder/main.go

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"flag"
7+
"fmt"
8+
"os"
9+
"os/signal"
10+
"sync"
11+
"syscall"
12+
"time"
13+
14+
"github.com/dnstapir/observation-encoder/internal/api"
15+
"github.com/dnstapir/observation-encoder/internal/app"
16+
"github.com/dnstapir/observation-encoder/internal/cert"
17+
"github.com/dnstapir/observation-encoder/internal/common"
18+
"github.com/dnstapir/observation-encoder/internal/logger"
19+
)
20+
21+
/* Rewritten if building with make */
22+
var version = "BAD-BUILD"
23+
var commit = "BAD-BUILD"
24+
25+
type conf struct {
26+
app.Conf
27+
Api api.Conf
28+
Cert cert.Conf `json:"cert"`
29+
}
30+
31+
func main() {
32+
var configFile string
33+
var runVersionCmd bool
34+
var debugFlag bool
35+
var mainConf conf
36+
37+
flag.BoolVar(&runVersionCmd,
38+
"version",
39+
false,
40+
"Print version then exit",
41+
)
42+
flag.StringVar(&configFile,
43+
"config",
44+
"",
45+
"Configuration file to use",
46+
)
47+
flag.BoolVar(&debugFlag,
48+
"debug",
49+
false,
50+
"Enable DEBUG logs",
51+
)
52+
flag.Parse()
53+
54+
log, err := logger.Create(
55+
logger.Conf{
56+
Debug: debugFlag,
57+
})
58+
if err != nil {
59+
panic(fmt.Sprintf("Could not create logger, err: '%s'", err))
60+
}
61+
62+
log.Info("observation-encoder version: '%s', commit: '%s'", version, commit)
63+
if runVersionCmd {
64+
os.Exit(0)
65+
}
66+
67+
log.Debug("Debug logging enabled")
68+
69+
if configFile == "" {
70+
log.Error("No config file specified, exiting...")
71+
os.Exit(-1)
72+
}
73+
74+
file, err := os.Open(configFile)
75+
if err != nil {
76+
log.Error("Couldn't open config file '%s', exiting...", configFile)
77+
os.Exit(-1)
78+
}
79+
defer file.Close()
80+
81+
confDecoder := json.NewDecoder(file)
82+
if confDecoder == nil {
83+
log.Error("Problem decoding config file '%s', exiting...", configFile)
84+
os.Exit(-1)
85+
}
86+
87+
confDecoder.DisallowUnknownFields()
88+
confDecoder.Decode(&mainConf)
89+
file.Close() // TODO okay to close here while also using defer above?
90+
91+
mainConf.Log = log
92+
appHandle, err := app.Create(mainConf.Conf)
93+
if err != nil {
94+
log.Error("Error creating application: '%s'", err)
95+
os.Exit(-1)
96+
}
97+
98+
mainConf.Cert.Log = log
99+
certHandle, err := cert.Create(mainConf.Cert)
100+
if err != nil {
101+
log.Error("Error creating cert manager: '%s'", err)
102+
os.Exit(-1)
103+
}
104+
105+
mainConf.Api.Log = log
106+
mainConf.Api.App = appHandle
107+
mainConf.Api.Certs = certHandle
108+
apiHandle, err := api.Create(mainConf.Api)
109+
if err != nil {
110+
log.Error("Error creating API: '%s'", err)
111+
os.Exit(-1)
112+
}
113+
114+
sigChan := make(chan os.Signal, 1)
115+
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
116+
defer close(sigChan)
117+
defer signal.Stop(sigChan)
118+
119+
ctx, cancel := context.WithCancel(context.Background())
120+
exitCh := make(chan common.Exit)
121+
122+
go appHandle.Run(ctx, exitCh)
123+
124+
go apiHandle.Run(ctx, exitCh)
125+
go certHandle.Run(ctx, exitCh)
126+
127+
exitLoop := false
128+
var wg sync.WaitGroup
129+
wg.Add(1)
130+
for {
131+
select {
132+
case s, ok := <-sigChan:
133+
if ok {
134+
log.Info("Got signal '%s'", s)
135+
exitLoop = true
136+
} else {
137+
log.Info("signal channel was closed")
138+
sigChan = nil
139+
}
140+
case exit, ok := <-exitCh:
141+
if ok {
142+
if exit.Err != nil {
143+
log.Error("%s exited with error: '%s'", exit.ID, exit.Err)
144+
if exit.Err == common.ErrFatal {
145+
exitLoop = true
146+
}
147+
} else {
148+
log.Info("%s done!", exit.ID)
149+
}
150+
} else {
151+
log.Warning("exit channel closed unexpectedly")
152+
exitCh = nil
153+
}
154+
}
155+
if exitLoop || (sigChan == nil && exitCh == nil) {
156+
log.Info("Leaving toplevel loop")
157+
wg.Done()
158+
break
159+
}
160+
}
161+
162+
log.Info("Cancelling, giving threads some time to finish...")
163+
cancel()
164+
timeout := make(chan bool, 1)
165+
go func() {
166+
time.Sleep(2 * time.Second)
167+
timeout <- true
168+
}()
169+
170+
TIMEOUT_LOOP:
171+
for {
172+
select {
173+
case exit, ok := <-exitCh:
174+
if ok {
175+
if exit.Err != nil {
176+
log.Error("%s exited with error: '%s'", exit.ID, exit.Err)
177+
} else {
178+
log.Info("%s done!", exit.ID)
179+
}
180+
} else {
181+
log.Info("exit channel was closed during shutdown")
182+
exitCh = nil
183+
}
184+
case <-timeout:
185+
log.Debug("Time's up. Proceeding with shutdown.")
186+
break TIMEOUT_LOOP
187+
}
188+
if exitCh == nil {
189+
log.Warning("exit channel closed unexpectedly")
190+
break TIMEOUT_LOOP
191+
}
192+
}
193+
194+
close(exitCh)
195+
wg.Wait()
196+
log.Info("Exiting...")
197+
os.Exit(0)
198+
}

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/dnstapir/observation-encoder
2+
3+
go 1.24.6

0 commit comments

Comments
 (0)