Skip to content
Merged
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
13 changes: 7 additions & 6 deletions consul/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,13 @@ func (n UpstreamNode) Equal(o UpstreamNode) bool {
}

type Downstream struct {
LocalBindAddress string
LocalBindPort int
Protocol string
TargetAddress string
TargetPort int
EnableForwardFor bool
LocalBindAddress string
LocalBindPort int
Protocol string
TargetAddress string
TargetPort int
EnableForwardFor bool
AppNameHeaderName string

TLS
}
Expand Down
29 changes: 17 additions & 12 deletions consul/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ type upstream struct {
}

type downstream struct {
LocalBindAddress string
LocalBindPort int
Protocol string
TargetAddress string
TargetPort int
EnableForwardFor bool
LocalBindAddress string
LocalBindPort int
Protocol string
TargetAddress string
TargetPort int
EnableForwardFor bool
AppNameHeaderName string
}

type certLeaf struct {
Expand Down Expand Up @@ -128,6 +129,9 @@ func (w *Watcher) handleProxyChange(first bool, srv *api.AgentService) {
if f, ok := srv.Proxy.Config["enable_forwardfor"].(bool); ok {
w.downstream.EnableForwardFor = f
}
if a, ok := srv.Proxy.Config["appname_header"].(string); ok {
w.downstream.AppNameHeaderName = a
}
}

keep := make(map[string]bool)
Expand Down Expand Up @@ -344,12 +348,13 @@ func (w *Watcher) genCfg() Config {
ServiceID: w.service,
CAsPool: w.certCAPool,
Downstream: Downstream{
LocalBindAddress: w.downstream.LocalBindAddress,
LocalBindPort: w.downstream.LocalBindPort,
TargetAddress: w.downstream.TargetAddress,
TargetPort: w.downstream.TargetPort,
Protocol: w.downstream.Protocol,
EnableForwardFor: w.downstream.EnableForwardFor,
LocalBindAddress: w.downstream.LocalBindAddress,
LocalBindPort: w.downstream.LocalBindPort,
TargetAddress: w.downstream.TargetAddress,
TargetPort: w.downstream.TargetPort,
Protocol: w.downstream.Protocol,
EnableForwardFor: w.downstream.EnableForwardFor,
AppNameHeaderName: w.downstream.AppNameHeaderName,

TLS: TLS{
CAs: w.certCAs,
Expand Down
4 changes: 1 addition & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ require (
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect
github.com/criteo/haproxy-spoe-go v0.0.0-20190925130734-97891c13d324
github.com/d4l3k/messagediff v1.2.1 // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/facebookgo/freeport v0.0.0-20150612182905-d4adf43b75b9
github.com/go-openapi/analysis v0.19.0 // indirect
github.com/go-openapi/jsonpointer v0.19.0 // indirect
github.com/go-openapi/jsonreference v0.19.0 // indirect
github.com/go-openapi/loads v0.19.0 // indirect
github.com/go-openapi/runtime v0.19.0 // indirect
github.com/go-openapi/spec v0.19.0 // indirect
github.com/haproxytech/models v1.2.0
github.com/haproxytech/models v1.2.4
github.com/hashicorp/consul v1.7.2
github.com/hashicorp/consul/api v1.4.0
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
Expand All @@ -23,7 +22,6 @@ require (
github.com/prometheus/client_golang v0.9.2
github.com/sirupsen/logrus v1.4.2
github.com/stretchr/testify v1.4.0
golang.org/x/text v0.3.2 // indirect
gopkg.in/d4l3k/messagediff.v1 v1.2.1
gopkg.in/mcuadros/go-syslog.v2 v2.2.1
)
153 changes: 8 additions & 145 deletions go.sum

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions haproxy/dataplane/http_request_rule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package dataplane

import (
"fmt"
"net/http"

"github.com/haproxytech/models"
)

func (c *Dataplane) HTTPRequestRules(parentType, parentName string) ([]models.HTTPRequestRule, error) {
type resT struct {
Data []models.HTTPRequestRule `json:"data"`
}

var res resT

err := c.makeReq(http.MethodGet, fmt.Sprintf("/v1/services/haproxy/configuration/http_request_rules?parent_type=%s&parent_name=%s", parentType, parentName), nil, &res)
if err != nil {
return nil, err
}

return res.Data, nil
}

func (t *tnx) CreateHTTPRequestRule(parentType, parentName string, rule models.HTTPRequestRule) error {
if err := t.ensureTnx(); err != nil {
return err
}
return t.client.makeReq(http.MethodPost, fmt.Sprintf("/v1/services/haproxy/configuration/http_request_rules?parent_type=%s&parent_name=%s&transaction_id=%s", parentType, parentName, t.txID), rule, nil)
}
9 changes: 9 additions & 0 deletions haproxy/spoe.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func (h *SPOEHandler) Handler(args []spoe.Message) ([]spoe.Action, error) {
}

authorized := err == nil
sourceApp := ""

if authorized {
certURI, err := connect.ParseCertURI(cert.URIs[0])
Expand All @@ -71,6 +72,9 @@ func (h *SPOEHandler) Handler(args []spoe.Message) ([]spoe.Action, error) {
log.Debugf("spoe: auth response from %s authorized=%v", certURI.URI().String(), resp.Authorized)

authorized = resp.Authorized
if sis, ok := certURI.(*connect.SpiffeIDService); ok {
sourceApp = sis.Service
}
}

res := 1
Expand All @@ -83,6 +87,11 @@ func (h *SPOEHandler) Handler(args []spoe.Message) ([]spoe.Action, error) {
Scope: spoe.VarScopeSession,
Value: res,
},
spoe.ActionSetVar{
Name: "source_app",
Scope: spoe.VarScopeSession,
Value: sourceApp,
},
}, nil
}
return nil, nil
Expand Down
4 changes: 4 additions & 0 deletions haproxy/state/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ func applyBackends(ha HAProxy, old, new []Backend) error {
return err
}
}

for _, r := range newBack.HTTPRequestRules {
err = ha.CreateHTTPRequestRule("backend", newBack.Backend.Name, r)
}
}

if !needCreate {
Expand Down
29 changes: 29 additions & 0 deletions haproxy/state/apply_backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,35 @@ func TestAddBackend(t *testing.T) {
ha.RequireOps(t, RequireOp(haOpCreateBackend, "back"))
}

func TestAddBackendHTTPRule(t *testing.T) {
old := State{}
new := State{
Backends: []Backend{
Backend{
Backend: models.Backend{
Name: "back",
},
HTTPRequestRules: []models.HTTPRequestRule{
{
HdrName: "X-App",
HdrFormat: "%[var(sess.connect.source_app)]",
},
},
},
},
}

ha := &fakeHA{}

err := Apply(ha, old, new)
require.Nil(t, err)

ha.RequireOps(t,
RequireOp(haOpCreateBackend, "back"),
RequireOp(haOpCreateHTTPRequestRule, "back"),
)
}

func TestNoChangeBackend(t *testing.T) {
old := State{
Backends: []Backend{
Expand Down
10 changes: 10 additions & 0 deletions haproxy/state/downstream.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,16 @@ func generateDownstream(opts Options, certStore CertificateStore, cfg consul.Dow
}
}

// App name header
if cfg.AppNameHeaderName != "" && beMode == models.BackendModeHTTP {
be.HTTPRequestRules = append(be.HTTPRequestRules, models.HTTPRequestRule{
ID: int64p(0),
Type: models.HTTPRequestRuleTypeAddHeader,
HdrName: cfg.AppNameHeaderName,
HdrFormat: "%[var(sess.connect.source_app)]",
})
}

state.Backends = append(state.Backends, be)

return state, nil
Expand Down
9 changes: 9 additions & 0 deletions haproxy/state/fake_ha_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const (
haOpCreateFilter
haOpCreateTCPRequestRule
haOpCreateLogTargets
haOpCreateHTTPRequestRule
)

type fakeHAOp struct {
Expand Down Expand Up @@ -136,3 +137,11 @@ func (h *fakeHA) CreateLogTargets(parentType, parentName string, rule models.Log
})
return nil
}

func (h *fakeHA) CreateHTTPRequestRule(parentType, parentName string, rule models.HTTPRequestRule) error {
h.ops = append(h.ops, fakeHAOp{
Type: haOpCreateHTTPRequestRule,
Name: parentName,
})
return nil
}
16 changes: 13 additions & 3 deletions haproxy/state/from_ha.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type HAProxyRead interface {
LogTargets(parentType, parentName string) ([]models.LogTarget, error)
Filters(parentType, parentName string) ([]models.Filter, error)
TCPRequestRules(parentType, parentName string) ([]models.TCPRequestRule, error)
HTTPRequestRules(parentType, parentName string) ([]models.HTTPRequestRule, error)
Backends() ([]models.Backend, error)
Servers(beName string) ([]models.Server, error)
}
Expand Down Expand Up @@ -100,10 +101,19 @@ func FromHAProxy(ha HAProxyRead) (State, error) {
lt = &logTargets[0]
}

reqRules, err := ha.HTTPRequestRules("backend", b.Name)
if err != nil {
return state, err
}
if len(reqRules) == 0 {
reqRules = nil
}

state.Backends = append(state.Backends, Backend{
Backend: b,
Servers: servers,
LogTarget: lt,
Backend: b,
Servers: servers,
LogTarget: lt,
HTTPRequestRules: reqRules,
})
}

Expand Down
17 changes: 13 additions & 4 deletions haproxy/state/snapshot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ import (
func GetTestConsulConfig() consul.Config {
return consul.Config{
Downstream: consul.Downstream{
LocalBindAddress: "127.0.0.2",
LocalBindPort: 9999,
TargetAddress: "128.0.0.5",
TargetPort: 8888,
LocalBindAddress: "127.0.0.2",
LocalBindPort: 9999,
TargetAddress: "128.0.0.5",
TargetPort: 8888,
AppNameHeaderName: "X-App",
},
Upstreams: []consul.Upstream{
consul.Upstream{
Expand Down Expand Up @@ -131,6 +132,14 @@ func GetTestHAConfig(baseCfg string) State {
Facility: models.LogTargetFacilityLocal0,
Format: models.LogTargetFormatRfc5424,
},
HTTPRequestRules: []models.HTTPRequestRule{
{
ID: int64p(0),
Type: models.HTTPRequestRuleTypeAddHeader,
HdrName: "X-App",
HdrFormat: "%[var(sess.connect.source_app)]",
},
},
},

// upstream backend
Expand Down
7 changes: 4 additions & 3 deletions haproxy/state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ type Frontend struct {
}

type Backend struct {
Backend models.Backend
LogTarget *models.LogTarget
Servers []models.Server
Backend models.Backend
LogTarget *models.LogTarget
Servers []models.Server
HTTPRequestRules []models.HTTPRequestRule
}

type State struct {
Expand Down
1 change: 1 addition & 0 deletions haproxy/state/states.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type HAProxy interface {
CreateFilter(parentType, parentName string, filter models.Filter) error
CreateTCPRequestRule(parentType, parentName string, rule models.TCPRequestRule) error
CreateLogTargets(parentType, parentName string, rule models.LogTarget) error
CreateHTTPRequestRule(parentType, parentName string, rule models.HTTPRequestRule) error
}

func Generate(opts Options, certStore CertificateStore, oldState State, cfg consul.Config) (State, error) {
Expand Down