Skip to content

Commit 59417d6

Browse files
ivanmatmatiMo3m3n
authored andcommitted
MEDIUM: Add controller builder
1 parent 255df4b commit 59417d6

File tree

3 files changed

+168
-141
lines changed

3 files changed

+168
-141
lines changed

external.go

Lines changed: 0 additions & 63 deletions
This file was deleted.

main.go

Lines changed: 43 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ package main
1717
import (
1818
_ "embed"
1919
"fmt"
20-
"log"
21-
"net/http"
2220
"os"
2321
"os/signal"
2422
"syscall"
@@ -27,13 +25,12 @@ import (
2725
_ "net/http/pprof"
2826

2927
"github.com/google/renameio"
30-
config "github.com/haproxytech/kubernetes-ingress/pkg/configuration"
28+
"github.com/jessevdk/go-flags"
29+
3130
c "github.com/haproxytech/kubernetes-ingress/pkg/controller"
3231
"github.com/haproxytech/kubernetes-ingress/pkg/controller/annotations"
3332
"github.com/haproxytech/kubernetes-ingress/pkg/store"
3433
"github.com/haproxytech/kubernetes-ingress/pkg/utils"
35-
"github.com/jessevdk/go-flags"
36-
"github.com/prometheus/client_golang/prometheus/promhttp"
3734
)
3835

3936
//go:embed fs/usr/local/etc/haproxy/haproxy.cfg
@@ -48,29 +45,58 @@ func main() {
4845
os.Exit(exitCode)
4946
}()
5047

48+
// Parse Controller Args
5149
var osArgs utils.OSArgs
50+
var err error
5251
parser := flags.NewParser(&osArgs, flags.IgnoreUnknown)
53-
_, err := parser.Parse()
54-
55-
if err != nil {
52+
if _, err = parser.Parse(); err != nil {
5653
fmt.Println(err)
5754
exitCode = 1
5855
return
5956
}
6057

61-
if osArgs.PromotheusPort != 0 {
62-
http.Handle("/metrics", promhttp.Handler())
63-
go func() {
64-
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", osArgs.PromotheusPort), nil))
65-
}()
66-
}
67-
58+
// Set Logger
6859
logger := utils.GetLogger()
6960
logger.SetLevel(osArgs.LogLevel.LogLevel)
61+
if len(osArgs.Help) > 0 && osArgs.Help[0] {
62+
parser.WriteHelp(os.Stdout)
63+
return
64+
}
65+
logger.ShowFilename(false)
66+
logInfo(logger, osArgs)
67+
logger.ShowFilename(true)
7068

69+
// Default annotations
7170
defaultBackendSvc := fmt.Sprint(osArgs.DefaultBackendService)
7271
defaultCertificate := fmt.Sprint(osArgs.DefaultCertificate)
72+
annotations.SetDefaultValue("default-backend-service", defaultBackendSvc)
73+
annotations.SetDefaultValue("ssl-certificate", defaultCertificate)
74+
75+
// Start Controller
76+
s := store.NewK8sStore(osArgs)
77+
for _, namespace := range osArgs.NamespaceWhitelist {
78+
s.NamespacesAccess.Whitelist[namespace] = struct{}{}
79+
}
80+
for _, namespace := range osArgs.NamespaceBlacklist {
81+
s.NamespacesAccess.Blacklist[namespace] = struct{}{}
82+
}
83+
controller := c.NewBuilder().WithStore(s).WithArgs(osArgs).Build()
84+
cfg := controller.Cfg
85+
err = renameio.WriteFile(cfg.Env.MainCFGFile, haproxyConf, 0755)
86+
if err != nil {
87+
logger.Panic(err)
88+
}
89+
logger.Error(os.Chdir(cfg.Env.CfgDir))
90+
controller.Start()
91+
92+
// Catch QUIT signals
93+
signalC := make(chan os.Signal, 1)
94+
signal.Notify(signalC, os.Interrupt, syscall.SIGTERM, syscall.SIGUSR1)
95+
<-signalC
96+
controller.Stop()
97+
}
7398

99+
func logInfo(logger utils.Logger, osArgs utils.OSArgs) {
74100
if len(osArgs.Version) > 0 {
75101
fmt.Printf("HAProxy Ingress Controller %s %s%s", GitTag, GitCommit, GitDirty)
76102
fmt.Printf("Build from: %s", GitRepo)
@@ -83,28 +109,16 @@ func main() {
83109
return
84110
}
85111

86-
if len(osArgs.Help) > 0 && osArgs.Help[0] {
87-
parser.WriteHelp(os.Stdout)
88-
return
89-
}
90-
91-
logger.FileName = false
92112
logger.Print(IngressControllerInfo)
93113
logger.Printf("HAProxy Ingress Controller %s %s%s", GitTag, GitCommit, GitDirty)
94114
logger.Printf("Build from: %s", GitRepo)
95115
logger.Printf("Build date: %s\n", BuildTime)
96-
if osArgs.PprofEnabled {
97-
logger.Warning("pprof endpoint exposed over https")
98-
go func() {
99-
logger.Error(http.ListenAndServe("127.0.0.1:6060", nil))
100-
}()
101-
}
102116
logger.Printf("ConfigMap: %s", osArgs.ConfigMap)
103117
logger.Printf("Ingress class: %s", osArgs.IngressClass)
104118
logger.Printf("Empty Ingress class: %t", osArgs.EmptyIngressClass)
105119
logger.Printf("Publish service: %s", osArgs.PublishService)
106-
logger.Printf("Default backend service: %s", defaultBackendSvc)
107-
logger.Printf("Default ssl certificate: %s", defaultCertificate)
120+
logger.Printf("Default backend service: %s", osArgs.DefaultBackendService)
121+
logger.Printf("Default ssl certificate: %s", osArgs.DefaultCertificate)
108122
if !osArgs.DisableHTTP {
109123
logger.Printf("Frontend HTTP listening on: %s:%d", osArgs.IPV4BindAddr, osArgs.HTTPBindPort)
110124
}
@@ -138,53 +152,4 @@ func main() {
138152
hostname, err := os.Hostname()
139153
logger.Error(err)
140154
logger.Printf("Running on %s", hostname)
141-
142-
cfg := config.ControllerCfg{
143-
Env: config.Env{
144-
HAProxyBinary: "/usr/local/sbin/haproxy",
145-
MainCFGFile: "/etc/haproxy/haproxy.cfg",
146-
CfgDir: "/etc/haproxy/",
147-
RuntimeDir: "/var/run",
148-
StateDir: "/var/state/haproxy/",
149-
},
150-
}
151-
if osArgs.External {
152-
cfg = setupHAProxyEnv(osArgs)
153-
}
154-
err = renameio.WriteFile(cfg.Env.MainCFGFile, haproxyConf, 0755)
155-
if err != nil {
156-
logger.Panic(err)
157-
}
158-
podName := os.Getenv("POD_NAME")
159-
160-
if osArgs.Program != "" {
161-
cfg.Env.HAProxyBinary = osArgs.Program
162-
}
163-
logger.Error(os.Chdir(cfg.Env.CfgDir))
164-
165-
prefix, errPrefix := utils.GetPodPrefix(podName)
166-
logger.Error(errPrefix)
167-
168-
controller := c.HAProxyController{
169-
Cfg: cfg,
170-
OSArgs: osArgs,
171-
PodNamespace: os.Getenv("POD_NAMESPACE"),
172-
PodPrefix: prefix}
173-
logger.FileName = true
174-
// K8s Store
175-
s := store.NewK8sStore(osArgs)
176-
annotations.SetDefaultValue("default-backend-service", defaultBackendSvc)
177-
annotations.SetDefaultValue("ssl-certificate", defaultCertificate)
178-
for _, namespace := range osArgs.NamespaceWhitelist {
179-
s.NamespacesAccess.Whitelist[namespace] = struct{}{}
180-
}
181-
for _, namespace := range osArgs.NamespaceBlacklist {
182-
s.NamespacesAccess.Blacklist[namespace] = struct{}{}
183-
}
184-
controller.Store = s
185-
controller.Start()
186-
signalC := make(chan os.Signal, 1)
187-
signal.Notify(signalC, os.Interrupt, syscall.SIGTERM, syscall.SIGUSR1)
188-
<-signalC
189-
controller.Stop()
190155
}

pkg/controller/builder.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package controller
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"os"
7+
"path"
8+
"path/filepath"
9+
10+
"github.com/prometheus/client_golang/prometheus/promhttp"
11+
12+
config "github.com/haproxytech/kubernetes-ingress/pkg/configuration"
13+
"github.com/haproxytech/kubernetes-ingress/pkg/store"
14+
"github.com/haproxytech/kubernetes-ingress/pkg/utils"
15+
)
16+
17+
type Builder struct {
18+
osArgs utils.OSArgs
19+
cfg config.ControllerCfg
20+
store store.K8s
21+
}
22+
23+
var defaultCfg = config.ControllerCfg{
24+
Env: config.Env{
25+
HAProxyBinary: "/usr/local/sbin/haproxy",
26+
MainCFGFile: "/etc/haproxy/haproxy.cfg",
27+
CfgDir: "/etc/haproxy/",
28+
RuntimeDir: "/var/run",
29+
StateDir: "/var/state/haproxy/",
30+
},
31+
}
32+
33+
func NewBuilder() *Builder {
34+
return &Builder{
35+
cfg: defaultCfg,
36+
}
37+
}
38+
39+
func (builder *Builder) WithStore(store store.K8s) *Builder {
40+
builder.store = store
41+
return builder
42+
}
43+
44+
func (builder *Builder) WithConfiguration(cfg config.ControllerCfg) *Builder {
45+
builder.cfg = cfg
46+
return builder
47+
}
48+
49+
func (builder *Builder) WithArgs(osArgs utils.OSArgs) *Builder {
50+
builder.osArgs = osArgs
51+
return builder
52+
}
53+
54+
func (builder *Builder) Build() *HAProxyController {
55+
if builder.osArgs.External {
56+
builder.cfg = setupExternalMode(builder.osArgs)
57+
}
58+
59+
if builder.osArgs.PromotheusPort != 0 {
60+
http.Handle("/metrics", promhttp.Handler())
61+
go func() {
62+
logger.Error(http.ListenAndServe(fmt.Sprintf(":%d", builder.osArgs.PromotheusPort), nil))
63+
}()
64+
}
65+
66+
if builder.osArgs.PprofEnabled {
67+
logger.Warning("pprof endpoint exposed over https")
68+
go func() {
69+
logger.Error(http.ListenAndServe("127.0.0.1:6060", nil))
70+
}()
71+
}
72+
73+
prefix, errPrefix := utils.GetPodPrefix(os.Getenv("POD_NAME"))
74+
logger.Error(errPrefix)
75+
76+
return &HAProxyController{
77+
Cfg: builder.cfg,
78+
OSArgs: builder.osArgs,
79+
PodNamespace: os.Getenv("POD_NAMESPACE"),
80+
PodPrefix: prefix,
81+
Store: builder.store,
82+
}
83+
}
84+
85+
// When controller is not running on a containerized
86+
// environment (out of Kubernetes)
87+
func setupExternalMode(osArgs utils.OSArgs) config.ControllerCfg {
88+
logger.Print("Running Controller out of K8s cluster")
89+
logger.FileName = true
90+
cfg := config.ControllerCfg{
91+
Env: config.Env{
92+
HAProxyBinary: "/usr/local/sbin/haproxy",
93+
MainCFGFile: "/tmp/haproxy-ingress/etc/haproxy.cfg",
94+
CfgDir: "/tmp/haproxy-ingress/etc",
95+
RuntimeDir: "/tmp/haproxy-ingress/run",
96+
StateDir: "/tmp/haproxy-ingress/state",
97+
},
98+
}
99+
100+
if osArgs.CfgDir != "" {
101+
cfg.Env.CfgDir = osArgs.CfgDir
102+
cfg.Env.MainCFGFile = path.Join(cfg.Env.CfgDir, "haproxy.cfg")
103+
}
104+
if osArgs.RuntimeDir != "" {
105+
cfg.Env.RuntimeDir = osArgs.RuntimeDir
106+
}
107+
if err := os.MkdirAll(cfg.Env.CfgDir, 0755); err != nil {
108+
logger.Panic(err)
109+
}
110+
if err := os.MkdirAll(cfg.Env.RuntimeDir, 0755); err != nil {
111+
logger.Panic(err)
112+
}
113+
114+
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
115+
if err != nil {
116+
logger.Panic(err)
117+
}
118+
logger.Debug(dir)
119+
120+
if osArgs.Program != "" {
121+
cfg.Env.HAProxyBinary = osArgs.Program
122+
}
123+
124+
return cfg
125+
}

0 commit comments

Comments
 (0)