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

Allow to pass haproxy defaults and global parameters as flag #77

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
52 changes: 52 additions & 0 deletions flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package main

import (
"fmt"
"strings"

"github.com/haproxytech/haproxy-consul-connect/haproxy"
)

type stringSliceFlag []string

func (i *stringSliceFlag) String() string {
return ""
}

func (i *stringSliceFlag) Set(value string) error {
*i = append(*i, value)
return nil
}

func makeHAProxyParams(flags stringSliceFlag) (haproxy.HAProxyParams, error) {
params := haproxy.HAProxyParams{
Defaults: map[string]string{},
Globals: map[string]string{},
}

for _, flag := range flags {
parts := strings.Split(flag, "=")
if len(parts) != 2 {
return params, fmt.Errorf("bad haproxy-param flag %s, expected {type}.{name}={value}", flag)
}

dot := strings.IndexByte(parts[0], '.')
if dot == -1 {
return params, fmt.Errorf("bad haproxy-param flag %s, expected {type}.{name}={value}", flag)
}

var t map[string]string
switch parts[0][:dot] {
case "defaults":
t = params.Defaults
case "global":
t = params.Globals
default:
return params, fmt.Errorf("bad haproxy-param flag %s, param type must be `defaults` or `global`", flag)
}

t[parts[0][dot+1:]] = parts[1]
}

return params, nil
}
31 changes: 31 additions & 0 deletions flags_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package main

import (
"testing"

"github.com/haproxytech/haproxy-consul-connect/haproxy"
"github.com/stretchr/testify/require"
)

func TestMakeHAProxyParams(t *testing.T) {
flags := stringSliceFlag{
"defaults.test.with.dots=3",
"defaults.another=abdc",
"global.with.spaces=hey I have spaces",
"global.with.dots=hey.I.have.dots",
}

r, err := makeHAProxyParams(flags)
require.NoError(t, err)

require.Equal(t, haproxy.HAProxyParams{
Defaults: map[string]string{
"test.with.dots": "3",
"another": "abdc",
},
Globals: map[string]string{
"with.spaces": "hey I have spaces",
"with.dots": "hey.I.have.dots",
},
}, r)
}
35 changes: 24 additions & 11 deletions haproxy/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package haproxy
import (
"crypto/rand"
"encoding/base64"
"fmt"
"io/ioutil"
"os"
"path"
Expand All @@ -14,18 +15,32 @@ import (
log "github.com/sirupsen/logrus"
)

var defaultsHAProxyParams = HAProxyParams{
Globals: map[string]string{
"stats": "timeout 2m",
"tune.ssl.default-dh-param": "1024",
"nbproc": "1",
"nbthread": fmt.Sprint(runtime.GOMAXPROCS(0)),
"ulimit-n": "65536",
"maxconn": "32000",
},
Defaults: map[string]string{
"http-reuse": "always",
},
}

const baseCfgTmpl = `
global
master-worker
stats socket {{.SocketPath}} mode 600 level admin expose-fd listeners
stats timeout 2m
tune.ssl.default-dh-param 1024
nbproc 1
nbthread {{.NbThread}}
ulimit-n 65536
{{ range $k, $v := .HAProxyParams.Globals}}
{{$k}} {{$v}}
{{ end }}

defaults
http-reuse always
{{ range $k, $v := .HAProxyParams.Defaults}}
{{$k}} {{$v}}
{{ end }}

userlist controller
user {{.DataplaneUser}} insecure-password {{.DataplanePass}}
Expand Down Expand Up @@ -53,11 +68,10 @@ spoe-message check-intentions
`

type baseParams struct {
NbThread int
SocketPath string
DataplaneUser string
DataplanePass string
LogsPath string
HAProxyParams HAProxyParams
}

type haConfig struct {
Expand All @@ -73,7 +87,7 @@ type haConfig struct {
LogsSock string
}

func newHaConfig(baseDir string, sd *lib.Shutdown) (*haConfig, error) {
func newHaConfig(baseDir string, params HAProxyParams, sd *lib.Shutdown) (*haConfig, error) {
cfg := &haConfig{}

sd.Add(1)
Expand Down Expand Up @@ -119,11 +133,10 @@ func newHaConfig(baseDir string, sd *lib.Shutdown) (*haConfig, error) {
cfg.DataplaneUser = "hapeoxy"

err = tmpl.Execute(cfgFile, baseParams{
NbThread: runtime.GOMAXPROCS(0),
SocketPath: cfg.StatsSock,
LogsPath: cfg.LogsSock,
DataplaneUser: cfg.DataplaneUser,
DataplanePass: cfg.DataplanePass,
HAProxyParams: defaultsHAProxyParams.With(params),
})
if err != nil {
sd.Done()
Expand Down
2 changes: 1 addition & 1 deletion haproxy/haproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func New(consulClient *api.Client, cfg chan consul.Config, opts Options) *HAProx
}

func (h *HAProxy) Run(sd *lib.Shutdown) error {
hc, err := newHaConfig(h.opts.ConfigBaseDir, sd)
hc, err := newHaConfig(h.opts.ConfigBaseDir, h.opts.HAProxyParams, sd)
if err != nil {
return err
}
Expand Down
26 changes: 26 additions & 0 deletions haproxy/options.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
package haproxy

type HAProxyParams struct {
Defaults map[string]string
Globals map[string]string
}

func (p HAProxyParams) With(other HAProxyParams) HAProxyParams {
new := HAProxyParams{
Defaults: map[string]string{},
Globals: map[string]string{},
}
for k, v := range p.Defaults {
new.Defaults[k] = v
}
for k, v := range other.Defaults {
new.Defaults[k] = v
}
for k, v := range p.Globals {
new.Globals[k] = v
}
for k, v := range other.Globals {
new.Globals[k] = v
}
return new
}

type Options struct {
HAProxyBin string
DataplaneBin string
Expand All @@ -9,4 +34,5 @@ type Options struct {
StatsListenAddr string
StatsRegisterService bool
LogRequests bool
HAProxyParams HAProxyParams
}
9 changes: 9 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ func validateRequirements(dataplaneBin, haproxyBin string) error {
}

func main() {
haproxyParamsFlag := stringSliceFlag{}

flag.Var(&haproxyParamsFlag, "haproxy-param", "Global or defaults Haproxy config parameter to set in config. Can be specified multiple times. Must be of the form `defaults.name=value` or `global.name=value`")
versionFlag := flag.Bool("version", false, "Show version and exit")
logLevel := flag.String("log-level", "INFO", "Log level")
consulAddr := flag.String("http-addr", "127.0.0.1:8500", "Consul agent address")
Expand Down Expand Up @@ -128,6 +131,11 @@ func main() {
log.Fatalf("Please specify -sidecar-for or -sidecar-for-tag")
}

haproxyParams, err := makeHAProxyParams(haproxyParamsFlag)
if err != nil {
log.Fatal(err)
}

consulLogger := &consulLogger{}
watcher := consul.New(serviceID, consulClient, consulLogger)
go func() {
Expand All @@ -145,6 +153,7 @@ func main() {
StatsListenAddr: *statsListenAddr,
StatsRegisterService: *statsServiceRegister,
LogRequests: ll == log.TraceLevel,
HAProxyParams: haproxyParams,
})
sd.Add(1)
go func() {
Expand Down