-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.go
151 lines (124 loc) · 3.63 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package main
import (
"context"
"flag"
logger "log"
"os"
"os/signal"
"syscall"
"time"
"hosts-generator/cmd"
"hosts-generator/cmd/file_writer"
"hosts-generator/cmd/generator"
"hosts-generator/cmd/parsers"
"hosts-generator/cmd/parsers/caddy"
"hosts-generator/cmd/parsers/kubernetes"
"hosts-generator/cmd/parsers/traefik_v2"
)
var (
localIP = flag.String("ip", "127.0.0.1", "specify custom ip to use in hosts file, example: '192.168.33.10'")
hostsFile = flag.String("file", file_writer.HostsLocation, "specify custom hosts file location, example: '/etc/hosts_custom'")
platform = flag.String("platform", "", "change line-endings style for hosts file, default: '', available: darwin, windows, linux")
quiet = flag.Bool("quiet", false, "disable logging")
period = flag.Int("freq", 5, "poll every N seconds")
watch = flag.Bool("watch", false, "enable API polling mode: true/false")
postfix = flag.String("postfix", "", "use unique postfix if 2 parallel instances are running")
skipWildcard = flag.Bool("skipWildcard", false, "remove wildcard entries in hosts file. "+
"Not all DNS servers support wildcard entries, so this option can be used to filter out unsupported entries.")
kubeConfig = flag.String("kubeconfig", "", "specify full path to kubeconfig")
traefikUrl = flag.String("traefikUrl", "", "specify custom traefik API url, example: 'http://127.0.0.1:8080/api'")
caddyURL = flag.String("caddyURL", "", "specify custom caddy API url, example: 'http://127.0.0.1:2019/config/'")
)
func main() {
flag.Parse()
lineEnding := detectLineEndings()
adapter := file_writer.NewFileHostsAdapter(*hostsFile)
writer := file_writer.NewWriter(&adapter, lineEnding, *postfix)
handleExit(writer)
clients := buildClientsConfig()
if len(clients) == 0 {
log("WARN: no clients configured")
}
appConfig := &cmd.AppConfig{
Clients: clients,
Writer: writer,
LineEnding: lineEnding,
TargetIP: *localIP,
SyncPeriod: time.Second * time.Duration(*period),
EnableWatch: *watch,
Logger: log,
SkipWildcard: *skipWildcard,
}
app := cmd.NewApp(appConfig)
err := app.Run(context.Background())
if err != nil {
log("runtime error: %+v", err)
err := app.Stop()
if err != nil {
log("failed to clear hosts: %+v", err)
}
os.Exit(1)
}
}
func buildClientsConfig() []parsers.Parser {
type clientConf struct {
enable bool
client parsers.Parser
}
clientsConf := []clientConf{
{len(*kubeConfig) != 0, kubernetes.NewKubernetesClient(*kubeConfig)},
{len(*traefikUrl) != 0, traefik_v2.NewTraefikV2Client(*traefikUrl)},
{len(*caddyURL) != 0, caddy.NewCaddyV3(*caddyURL)},
}
clients := make([]parsers.Parser, 0)
for _, cc := range clientsConf {
if cc.enable {
clients = append(clients, cc.client)
}
}
logger.Println("loaded clients", len(clients))
return clients
}
func handleExit(writer *file_writer.Writer) {
c := make(chan os.Signal)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
log("stop signal received")
err := writer.Clear()
if err != nil {
log("failed to clear hosts: %+v", err)
}
os.Exit(0)
}()
}
func log(fmt string, params ...interface{}) {
if *quiet {
return
}
if len(params) == 0 {
logger.Printf(fmt)
} else {
logger.Printf(fmt, params...)
}
}
func detectLineEndings() string {
lineEnding := generator.LineEnding
if *platform != "" {
switch *platform {
case "linux":
lineEnding = "\n"
break
case "darwin":
lineEnding = "\n"
break
case "windows":
lineEnding = "\r\n"
break
default:
log("Unknown platform specified: %s, supported: linux, darwin, windows", *platform)
os.Exit(1)
}
}
return lineEnding
}