haproxytech / config-parser Goto Github PK
View Code? Open in Web Editor NEWHAProxy configuration parser
License: Apache License 2.0
HAProxy configuration parser
License: Apache License 2.0
I was trying to dynamically set the following attributes
server-state-file
server-state-base
hard-stop-after
lua-load
ssl-dh-param-file
ssl-engine
ssl-mode-async
ssl-default-bind-ciphersuites
ssl-default-server-ciphersuites
load-server-state-from-file
options
no option
Tried as the following, YMMV
var err error
err = p.Set(parser.Global, parser.GlobalSectionName, "server-state-file", &types.StringC{Value: "state-global"})
println(err)
// attribute not found
I'm getting the attribute not found
error, even if I use the right parsers and section name according to each attribute.
Any plan to implement these attributes?
There is missing options on program
section.
https://cbonte.github.io/haproxy-dconv/2.1/configuration.html#3.7-option%20start-on-reload
func getProgramParser() *Parsers {
return createParsers([]ParserInterface{
&simple.String{Name: "command"},
})
}
Assuming
import (
parser "github.com/haproxytech/config-parser/v5"
)
...
p := parser.New(content, options)
Currently it's possible to obtain the parsed models for all supported attributes like
log, err := p.Get(parser.Global, parser.GlobalSectionName, "log") // ([]types.Log, error)
...
It's also possible to update the data associated with the same attribute
err := p.Set(parser.Global, parser.GlobalSectionName, "log", log)
One can also render the full config using
p.String()
Proposal
In one of our use cases, we would like to obtain the resulting lines from such updates for a given attribute path.
So e.g.
lines, err := p.Render(parser.Global, parser.GlobalSectionName, "log")
Currently the lack of such granular access prevents us from effectively using the Config Parser code for our use case.
(Happily) wiling to contribute code if this feature makes sense.
$ go clean; go build
..\..\..\..\..\..\github.com\haproxytech\client-native\configuration\acl.go:23:2: cannot find package "github.com/haproxytech/config-parser/v3" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3 (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3 (from $GOPATH)
..\..\..\..\..\..\github.com\haproxytech\client-native\configuration\configuration.go:26:2: cannot find package "github.com/haproxytech/config-parser/v3/common" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\common (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\common (from $GOPATH)
..\..\..\..\..\..\github.com\haproxytech\client-native\configuration\acl.go:24:2: cannot find package "github.com/haproxytech/config-parser/v3/errors" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\errors (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\errors (from $GOPATH)
..\..\..\..\..\..\github.com\haproxytech\client-native\configuration\bind.go:27:2: cannot find package "github.com/haproxytech/config-parser/v3/params" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\params (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\params (from $GOPATH)
..\..\..\..\..\..\github.com\haproxytech\client-native\configuration\configuration.go:29:2: cannot find package "github.com/haproxytech/config-parser/v3/parsers" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\parsers (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\parsers (from $GOPATH)
..\..\..\..\..\..\github.com\haproxytech\client-native\configuration\filter.go:25:2: cannot find package "github.com/haproxytech/config-parser/v3/parsers/filters" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\parsers\filters (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\parsers\filters (from $GOPATH)
..\..\..\..\..\..\github.com\haproxytech\client-native\configuration\http_request_rule.go:27:2: cannot find package "github.com/haproxytech/config-parser/v3/parsers/http/actions" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\parsers\http\actions (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\parsers\http\actions (from $GOPATH)
..\..\..\..\..\..\github.com\haproxytech\client-native\configuration\configuration.go:30:2: cannot find package "github.com/haproxytech/config-parser/v3/parsers/stats/settings" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\parsers\stats\settings (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\parsers\stats\settings (from $GOPATH)
..\..\..\..\..\..\github.com\haproxytech\client-native\configuration\tcp_request_rule.go:27:2: cannot find package "github.com/haproxytech/config-parser/v3/parsers/tcp/actions" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\parsers\tcp\actions (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\parsers\tcp\actions (from $GOPATH)
..\..\..\..\..\..\github.com\haproxytech\client-native\configuration\tcp_request_rule.go:28:2: cannot find package "github.com/haproxytech/config-parser/v3/parsers/tcp/types" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\parsers\tcp\types (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\parsers\tcp\types (from $GOPATH)
..\..\..\..\..\..\github.com\haproxytech\client-native\configuration\transaction.go:33:2: cannot find package "github.com/haproxytech/config-parser/v3/spoe" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\spoe (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\spoe (from $GOPATH)
..\..\..\..\..\..\github.com\haproxytech\client-native\configuration\acl.go:25:2: cannot find package "github.com/haproxytech/config-parser/v3/types" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\types (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\types (from $GOPATH)
$ go get -v
github.com/haproxytech/config-parser (download)
package github.com/haproxytech/config-parser/v3: cannot find package "github.com/haproxytech/config-parser/v3" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3 (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3 (from $GOPATH)
package github.com/haproxytech/config-parser/v3/common: cannot find package "github.com/haproxytech/config-parser/v3/common" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\common (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\common (from $GOPATH)
package github.com/haproxytech/config-parser/v3/errors: cannot find package "github.com/haproxytech/config-parser/v3/errors" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\errors (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\errors (from $GOPATH)
package github.com/haproxytech/config-parser/v3/params: cannot find package "github.com/haproxytech/config-parser/v3/params" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\params (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\params (from $GOPATH)
package github.com/haproxytech/config-parser/v3/parsers: cannot find package "github.com/haproxytech/config-parser/v3/parsers" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\parsers (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\parsers (from $GOPATH)
package github.com/haproxytech/config-parser/v3/parsers/filters: cannot find package "github.com/haproxytech/config-parser/v3/parsers/filters" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\parsers\filters (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\parsers\filters (from $GOPATH)
package github.com/haproxytech/config-parser/v3/parsers/http/actions: cannot find package "github.com/haproxytech/config-parser/v3/parsers/http/actions" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\parsers\http\actions (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\parsers\http\actions (from $GOPATH)
package github.com/haproxytech/config-parser/v3/parsers/stats/settings: cannot find package "github.com/haproxytech/config-parser/v3/parsers/stats/settings" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\parsers\stats\settings (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\parsers\stats\settings (from $GOPATH)
package github.com/haproxytech/config-parser/v3/parsers/tcp/actions: cannot find package "github.com/haproxytech/config-parser/v3/parsers/tcp/actions" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\parsers\tcp\actions (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\parsers\tcp\actions (from $GOPATH)
package github.com/haproxytech/config-parser/v3/parsers/tcp/types: cannot find package "github.com/haproxytech/config-parser/v3/parsers/tcp/types" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\parsers\tcp\types (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\parsers\tcp\types (from $GOPATH)
package github.com/haproxytech/config-parser/v3/spoe: cannot find package "github.com/haproxytech/config-parser/v3/spoe" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\spoe (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\spoe (from $GOPATH)
package github.com/haproxytech/config-parser/v3/types: cannot find package "github.com/haproxytech/config-parser/v3/types" in any of:
c:\go\src\github.com\haproxytech\config-parser\v3\types (from $GOROOT)
C:\Users\anupa\go\src\github.com\haproxytech\config-parser\v3\types (from $GOPATH)
Hello,
We have a load of old haproxy 1.5 instances that we're trying to parse the configuration from in order to move them to a newer version (via internal orchestration), however they were all set up using the listen
directive alone, for example:
listen https-passthru-fe 172.21.126.151:443
mode tcp
acl hdrcheck hdr(Host) -i bar.com
use_backend bar_backend
default_backend foo_backend
Rather than using the frontend
directive with a bind
, as would be expected today:
frontend https-passthru-fe
bind 172.21.126.151:443
mode tcp
acl hdrcheck hdr(Host) -i bar.com
use_backend bar_backend
default_backend foo_backend
It appears the Listen
section isn't configured with the same set of parsers as Frontend
.
Given this code:
package main
import (
"fmt"
parser "github.com/haproxytech/config-parser/v4"
"github.com/haproxytech/config-parser/v4/options"
)
func main() {
p, err := parser.New(options.Path("example.cfg"))
if err != nil {
panic(err)
}
frontends, err := p.SectionsGet(parser.Listen)
if err != nil {
panic(err)
}
fmt.Printf("Frontends: %+v\n", frontends)
frontendCount := 0
for _, frontend := range frontends {
frontendCount++
data, err := p.Get(parser.Listen, frontend, "acl")
if err != nil {
fmt.Printf("error getting frontend: %s, data: %+v\n", err, data)
continue
}
fmt.Printf("FE %s ACLs: %+v\n", frontend, data)
}
}
The first example will fail to parse the ACLs:
Frontends: [stats 23173-172.21.126.151:443]
error getting frontend ACLs: parser missing, data: <nil>
Changing the section to parser.Frontend
for both *Get()s, will result in the first example not being parsed at all (which I would assume is the correct behaviour), but the the second example returns the expected ACL data.
FE https-passthru-fe ACLs: [{Name:hdrcheck Criterion:hdr(host) Value:-i bar.com Comment:}]
Does it make sense to add the same set of parsers to the Listen section as you have for the Frontend in order to support this type of configuration?
how to get *:5000 in this situation?
frontend main *:5000
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js
use_backend static if url_static
default_backend app
hello, very thanks for this project, I am a chinese user.
I don't find the force-persist parser and option allbackups in config-parser/v4/parsers/.
I write a force-persist_generated.go
can you support this ?
Currently several section parsers such as peers, mailer, server-template try to determine address and port by splitting string by ':' and using second part as port which is incorrect when the address is IPv6 address. For example in peers section if peer is defined as peer fd00:aaaa:bbbb:cccc::1:1234
it wouldn't be parsed correctly and will not appear in configuration client's GetPeerEntries()
result.
I am using haproxy container and to keep configuration file deployments simple. I would say one should just ignore this entry when haproxy is not started with -W
I am now using an environment variable to set the master worker mode.
[ALERT] 200/122357 (2214360) : Can't use a 'program' section without master worker mode.
[ALERT] 200/122357 (2214360) : Fatal errors found in configuration.
When I add to a working config these lines, and restart haproxy ( haproxy -W -db -f /usr/local/etc/haproxy/haproxy.cfg)
program api
no option start-on-reload
command /usr/local/bin/dataplaneapi --host 0.0.0.0 --port 5555 --haproxy-bin '/usr/local/sbin/haproxy' --config-file $HAPROXY_CFG --reload-cmd '' --reload-delay 5 --userlist controller
I am getting these errors
[NOTICE] 200/133115 (2244182) : New program 'api' (2244183) forked
[NOTICE] 200/133115 (2244182) : New worker #1 (2244184) forked
[WARNING] 200/133115 (2244184) : [haproxy.main()] Failed to drop supplementary groups. Using 'gid'/'group' without 'uid'/'user' is generally useless.
expected argument for flag `-r, --reload-cmd'
[ALERT] 200/133115 (2244182) : Current program 'api' (2244183) exited with code 1 (Exit)
[ALERT] 200/133115 (2244182) : exit-on-failure: killing every processes with SIGTERM
[ALERT] 200/133115 (2244182) : Current worker #1 (2244184) exited with code 143 (Terminated)
[WARNING] 200/133115 (2244182) : All workers exited. Exiting... (1)
I0720 15:31:15.998927 2244150 executor.cpp:1013] Command exited with status 1 (pid: 2244180)
The parser ignores the final line of a configuration file if the line is not terminated by a newline.
For example:
backend 23173_https_144_147\n
balance leastconn\n
mode tcp\n
timeout connect 50s\n
timeout server 50s\n
server https_144_147-8083 172.21.126.147:443 check check-ssl inter 3000 rise 2 fall 2 weight 1\n
server https_144_147-8082 172.21.126.144:443 check check-ssl inter 3000 rise 2 fall 2 weight 1
In the above snippet (with delimiters added for clarity), the final server
line will be ignored by the parser when retrieving the servers.
package main
import (
"fmt"
parser "github.com/haproxytech/config-parser/v4"
"github.com/haproxytech/config-parser/v4/options"
"github.com/haproxytech/config-parser/v4/types"
)
func main() {
p, err := parser.New(options.Path("example.cfg"))
if err != nil {
panic(err)
}
backends, err := p.SectionsGet(parser.Backends)
if err != nil {
panic(err)
}
fmt.Printf("Backends: %+v\n", backends)
for _, backend := range backends {
data, _ := p.Get(parser.Backends, backend, "server")
servers, _ := data.([]types.Server)
backendAddrs := make([]string, 0, len(servers))
for i := range servers {
backendAddrs = append(backendAddrs, servers[i].Address)
}
fmt.Printf("BE Servers: %+v\n", backendAddrs)
}
}
Backends: [23173_https_144_147]
BE Servers: [172.21.126.147:443]
Adding a final terminating newline results in the correct parsing:
Backends: [23173_https_144_147]
BE Servers: [172.21.126.147:443 172.21.126.144:443]
Thanks
This works
datar, err := p.Get(parser.Backends, bkname, "server")
I also needed to parse server-template
This doesn't works
datat, err := p.Get(parser.Backends, bkname, "server-template")
Also is there a way to get a All Section line in a formatted way
So even if a attribute is not supported we can parse it ourself
Assuming
import (
parser "github.com/haproxytech/config-parser/v5"
)
...
p := parser.New(content, options)
Proposal
It would be a useful feature, to be able to list all the set attributes in a given section
E.g.
attributes, err := p.AttributesGet(parser.Global, parser.GlobalSectionName) // ([]string, error)
This would allow a piece of code to iterate over the existing attributes.
Currently it's not even possible to list the registered attributes for a given section type, so if some code wanted to enumerate all the attributes e.g. in a loop, it'd need to maintain a list of attributes, while this information is readily available for the parser (both the possible (via ConfiguredParsers), and the actually set attributes (via Parsers))
(Happily) wiling to contribute code if this feature makes sense.
First of all thank you for your great work folks. 🤗
So I've created haproxy.org/backend-config-snippet
and I added a acl line with comment like
acl is_whitelisted src 1.2.3.4 # don't use on production
and I got SIGSEV!
I rolled back config and then tried to reproduce it and the
is causing the panic in configParser.
Here's the stacktrace:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x58 pc=0xdbcaa4]
goroutine 32 [running]:
github.com/haproxytech/config-parser/v4.(*configParser).ProcessLine(_, {_, _}, {_, _, _}, {_, _}, {{}, {0x1b48ae1, ...}, ...})
/go/pkg/mod/github.com/haproxytech/config-parser/[email protected]/reader.go:155 +0xa24
github.com/haproxytech/config-parser/v4.(*configParser).Process(0xc0000f2840, {0x1d7ee80, 0xc000948990})
/go/pkg/mod/github.com/haproxytech/config-parser/[email protected]/reader.go:90 +0x61a
github.com/haproxytech/config-parser/v4.New({0xc000776040, 0x1, 0xc000d06420})
/go/pkg/mod/github.com/haproxytech/config-parser/[email protected]/parser.go:112 +0x1bd
github.com/haproxytech/client-native/v3/configuration.(*client).AddParser(0xc00049bd40, {0xc000d06420, 0x24})
/go/pkg/mod/github.com/haproxytech/client-native/[email protected]/configuration/configuration.go:131 +0x25f
github.com/haproxytech/client-native/v3/configuration.(*Transaction).startTransaction(0xc00049bd40, 0x3, 0x0)
/go/pkg/mod/github.com/haproxytech/client-native/[email protected]/configuration/transaction.go:128 +0x2d5
github.com/haproxytech/client-native/v3/configuration.(*Transaction).StartTransaction(0x0, 0xc0017cd330)
/go/pkg/mod/github.com/haproxytech/client-native/[email protected]/configuration/transaction.go:99 +0x1b
github.com/haproxytech/kubernetes-ingress/pkg/haproxy/api.(*clientNative).APIStartTransaction(0xc000450ba0)
/src/pkg/haproxy/api/api.go:128 +0x76
github.com/haproxytech/kubernetes-ingress/pkg/controller.(*HAProxyController).clientAPIClosure(0xc000172f00, 0xc0017cd440)
/src/pkg/controller/controller.go:58 +0x49
github.com/haproxytech/kubernetes-ingress/pkg/controller.(*HAProxyController).setToReady(0xc000172f00)
/src/pkg/controller/controller.go:177 +0x4f
github.com/haproxytech/kubernetes-ingress/pkg/controller.(*HAProxyController).updateHAProxy(0xc000172f00)
/src/pkg/controller/controller.go:152 +0x505
github.com/haproxytech/kubernetes-ingress/pkg/controller.(*HAProxyController).SyncData(0xc000172f00)
/src/pkg/controller/monitor.go:36 +0x457
github.com/haproxytech/kubernetes-ingress/pkg/controller.(*HAProxyController).Start(0xc000172f00)
/src/pkg/controller/controller.go:81 +0x125
created by main.main
/src/main.go:118 +0xac5
that led me to
Line 155 in 7d0ec01
I know it was rude of me to use such char in a comment especialy in the endline comment, but nevertheless I created this issue.
acl jh env(HAPROXY_LOCALPEER) -m beg jh
acl tz env(HAPROXY_LOCALPEER) -m beg tz
force-persist if jh || tz
force-persist not support || ?
config-parser/parsers/force-persist.go
Line 31 in b7f6fa2
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.