Skip to content
This repository was archived by the owner on Feb 19, 2024. It is now read-only.

Commit 4edd2bf

Browse files
committed
Initial commit
0 parents  commit 4edd2bf

File tree

6 files changed

+145
-0
lines changed

6 files changed

+145
-0
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/haproxy-config-diff

Diff for: examples/new.cfg

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
global
2+
log stdout format raw local0 info
3+
4+
defaults
5+
timeout client 10s
6+
timeout server 10s
7+
timeout connect 5s
8+
9+
10+
backend be_proxy
11+
server localhost 127.0.0.1:8080
12+
13+
14+
# Beispielconfig mit anderem Kommentar
15+
frontend fe_proxy
16+
bind 0.0.0.0:80
17+
18+
default_backend be_proxy

Diff for: examples/old.cfg

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
global
2+
log stdout format raw local0 info
3+
4+
defaults
5+
timeout connect 5s
6+
timeout server 10s
7+
timeout client 20s
8+
9+
# Beispielconfig
10+
frontend fe_proxy
11+
bind 0.0.0.0:80
12+
13+
default_backend be_proxy
14+
15+
backend be_proxy
16+
server localhost 127.0.0.1:8080

Diff for: go.mod

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module github.com/babiel/haproxy-config-diff
2+
3+
go 1.22.0
4+
5+
require github.com/google/go-cmp v0.6.0

Diff for: go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
2+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=

Diff for: main.go

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// haproxy-config-diff parset 2 HAProxy-Configs (grob),
2+
// erstellt daraus jeweils eine Datenstruktur
3+
// und vergleicht dann die 2 Datenstrukturen.
4+
//
5+
// Dadurch kann man inhaltliche Änderungen zwischen zwei Configs sehen,
6+
// aber Änderungen an Formatierungen und (irrelevanter) Reihenfolge werden ignoriert.
7+
package main
8+
9+
import (
10+
"bufio"
11+
"fmt"
12+
"io"
13+
"log"
14+
"os"
15+
"sort"
16+
"strings"
17+
18+
"github.com/google/go-cmp/cmp"
19+
)
20+
21+
type config map[string]map[string]section
22+
type section map[string][]string
23+
24+
func parseConfig(r io.Reader) (*config, error) {
25+
cfg := make(config)
26+
var currentSection section
27+
28+
scanner := bufio.NewScanner(r)
29+
for scanner.Scan() {
30+
s := strings.TrimSpace(scanner.Text())
31+
if s == "" {
32+
continue
33+
}
34+
35+
if strings.HasPrefix(s, "#") {
36+
continue
37+
}
38+
39+
keyword, params, _ := strings.Cut(s, " ")
40+
41+
switch keyword {
42+
case "global", "defaults", "listen", "frontend", "backend", "cache", "userlist", "peers":
43+
// vorherige Section abschließen.
44+
sort.Strings(currentSection["timeout"])
45+
sort.Strings(currentSection["acl"])
46+
sort.Strings(currentSection["bind"])
47+
sort.Strings(currentSection["server"])
48+
sort.Strings(currentSection["option"])
49+
sort.Strings(currentSection["stats"])
50+
51+
currentSection = make(section)
52+
if cfg[keyword] == nil {
53+
cfg[keyword] = make(map[string]section)
54+
}
55+
cfg[keyword][params] = currentSection
56+
default:
57+
if currentSection == nil {
58+
return nil, fmt.Errorf("keyword %q must be in a section", keyword)
59+
}
60+
currentSection[keyword] = append(currentSection[keyword], params)
61+
}
62+
}
63+
if err := scanner.Err(); err != nil {
64+
return nil, err
65+
}
66+
67+
return &cfg, nil
68+
}
69+
70+
func parseConfigFile(fp string) (*config, error) {
71+
f, err := os.Open(fp)
72+
if err != nil {
73+
return nil, err
74+
}
75+
defer f.Close()
76+
77+
cfg, err := parseConfig(f)
78+
if err != nil {
79+
return nil, fmt.Errorf("%s: %v", fp, err)
80+
}
81+
82+
return cfg, nil
83+
}
84+
85+
func main() {
86+
if len(os.Args) != 3 {
87+
fmt.Println("Usage: haproxy-config-diff FILE FILE")
88+
os.Exit(1)
89+
}
90+
91+
lhs, err := parseConfigFile(os.Args[1])
92+
if err != nil {
93+
log.Fatal(err)
94+
}
95+
96+
rhs, err := parseConfigFile(os.Args[2])
97+
if err != nil {
98+
log.Fatal(err)
99+
}
100+
101+
diff := cmp.Diff(lhs, rhs)
102+
fmt.Println(diff)
103+
}

0 commit comments

Comments
 (0)