Skip to content

Commit 078abb6

Browse files
committed
Fixes #242
1 parent 135cddb commit 078abb6

File tree

7 files changed

+88
-44
lines changed

7 files changed

+88
-44
lines changed

actions/reconfigure_test.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,24 +287,42 @@ backend myService-be1234
287287
s.Equal(expected, actual)
288288
}
289289

290+
// xxx
290291
func (s ReconfigureTestSuite) Test_GetTemplates_AddsHttpAuth_WhenModeIsSwarmAndUsersIsPresent() {
291292
s.reconfigure.Users = []proxy.User{
292293
{Username: "user-1", Password: "pass-1"},
293294
{Username: "user-2", Password: "pass-2"},
294295
}
295296
s.reconfigure.Mode = "swarm"
296-
s.reconfigure.Service.ServiceDest[0].Port = "1234"
297+
s.reconfigure.HttpsPort = 3333
298+
sd := []proxy.ServiceDest{
299+
{Port: "1111"},
300+
{Port: "2222", IgnoreAuthorization: true},
301+
}
302+
s.reconfigure.Service.ServiceDest = sd
297303
expected := `userlist myServiceUsers
298304
user user-1 insecure-password pass-1
299305
user user-2 insecure-password pass-2
300306
301307
302-
backend myService-be1234
308+
backend myService-be1111
303309
mode http
304-
server myService myService:1234
310+
server myService myService:1111
305311
acl myServiceUsersAcl http_auth(myServiceUsers)
306312
http-request auth realm myServiceRealm if !myServiceUsersAcl
307-
http-request del-header Authorization`
313+
http-request del-header Authorization
314+
backend myService-be2222
315+
mode http
316+
server myService myService:2222
317+
backend https-myService-be1111
318+
mode http
319+
server myService myService:3333
320+
acl myServiceUsersAcl http_auth(myServiceUsers)
321+
http-request auth realm myServiceRealm if !myServiceUsersAcl
322+
http-request del-header Authorization
323+
backend https-myService-be2222
324+
mode http
325+
server myService myService:3333`
308326

309327
_, actual, _ := s.reconfigure.GetTemplates()
310328

@@ -316,7 +334,6 @@ func (s ReconfigureTestSuite) Test_GetTemplates_AddsHttpsPort_WhenPresent() {
316334
backend myService-be1234
317335
mode http
318336
server myService myService:1234
319-
320337
backend https-myService-be1234
321338
mode http
322339
server myService myService:4321`

docs/usage.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ The following query parameters can be used to send a *reconfigure* request to *D
2222
|delReqHeader |Additional headers that will be deleted in the request before forwarding it to the service. Multiple headers should be separated with comma (`,`). Please consult [Delete a header in the request](https://www.haproxy.com/doc/aloha/7.0/haproxy/http_rewriting.html#delete-a-header-in-the-request) for more info.<br>Example: `X-Forwarded-For,Cookie`| |
2323
|delResHeader |Additional headers that will be deleted in the response before forwarding it to the client. Multiple headers should be separated with comma (`,`). Please consult [Delete a header in the response](https://www.haproxy.com/doc/aloha/7.0/haproxy/http_rewriting.html#delete-a-header-in-the-response) for more info.<br>Example: `X-Varnish,X-Cache`| |
2424
|httpsPort |The internal HTTPS port of a service that should be reconfigured. The port is used only in the `swarm` mode. If not specified, the `port` parameter will be used instead.<br>Example: `443`| |
25-
|isDefaultBackend | If true, the service will be set to the default_backend rule, meaning it will catch all requests not matching any other rules.<br>Example: `true`| |
25+
|ignoreAuthorization|If set to true, the service destination will not require authorization. The parameter must be prefixed with the index of the service destion that should be excluded from authorization.<br>Example: true|false|
26+
|isDefaultBackend |If set to true, the service will be set to the default_backend rule, meaning it will catch all requests not matching any other rules.<br>Example: `true`|false|
2627
|port |The internal port of a service that should be reconfigured. The port is used only in the `swarm` mode. The parameter can be prefixed with an index thus allowing definition of multiple destinations for a single service (e.g. `port.1`, `port.2`, and so on). This field is **mandatory** when running in `swarm` or `service` mode.<br>Example: `8080`| |
2728
|reqMode |The request mode. The proxy should be able to work with any mode supported by HAProxy. However, actively supported and tested modes are `http`, `tcp`, and `sni`. The `sni` mode implies TCP with an SNI-based routing. The parameter can be prefixed with an index thus allowing definition of multiple modes for a single service (e.g. `http`, `tcp`, and so on).<br>Example: `tcp`|http|
2829
|reqPathReplace |A regular expression to apply the modification.<br>Example: `/demo/`| |
@@ -37,7 +38,7 @@ The following query parameters can be used to send a *reconfigure* request to *D
3738
|timeoutTunnel |The tunnel timeout in seconds.<br>Example: `3600` |3600 |
3839
|xForwardedProto|Whether to add "X-Forwarded-Proto https" header.<br>Example: `true` |false |
3940

40-
Multiple destinations for a single service can be specified by adding index as a suffix to `servicePath`, `srcPort`, `port`, `userAgent`, and `ReqMode` parameters. In that case, `srcPort` is required. Defining multiple destinations is useful in cases when a service exposes multiple ports with different paths and functions.
41+
Multiple destinations for a single service can be specified by adding index as a suffix to `servicePath`, `srcPort`, `port`, `userAgent`, `ignoreAuthorization` or `ReqMode` parameters. In that case, `srcPort` is required.
4142

4243
### HTTP Mode HTTP Query Parameters
4344

@@ -61,7 +62,7 @@ The following query parameters can be used only when `reqMode` is set to `http`
6162
|usersPassEncrypted|Indicates whether passwords provided by `users` or `usersSecret` contain encrypted data. Passwords can be encrypted with the command `mkpasswd -m sha-512 password1`.<br>Example: `true`|false|
6263
|verifyClientSsl|Whether to verify client SSL and, if it is not valid, deny request and return 403 Forbidden status code. SSL is validated against the `ca-file` specified through the environment variable `CA_FILE`.<br>Example: true|false|
6364

64-
Multiple destinations for a single service can be specified by adding index as a suffix to `servicePath`, `srcPort`, `port`, `userAgent`, and `ReqMode` parameters. In that case, `srcPort` is required. Defining multiple destinations is useful in cases when a service exposes multiple ports with different paths and functions.
65+
Multiple destinations for a single service can be specified by adding index as a suffix to `servicePath`, `srcPort`, `port`, `userAgent`, `ignoreAuthorization`, or `ReqMode` parameters. In that case, `srcPort` is required.
6566

6667
### TCP Mode HTTP Query Parameters
6768

integration_tests/integration_swarm_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,12 @@ func (s IntegrationSwarmTestSuite) Test_ServiceAuthentication() {
366366
s.reconfigureGoDemo("")
367367
}()
368368

369+
// Add authorization
370+
369371
s.reconfigureGoDemo("&users=admin:password")
370372

373+
// Proxy returns 401 when user/pass is NOT provided
374+
371375
resp, err := s.sendHelloRequest()
372376

373377
if err != nil {
@@ -376,6 +380,8 @@ func (s IntegrationSwarmTestSuite) Test_ServiceAuthentication() {
376380
s.Equal(401, resp.StatusCode, s.getProxyConf())
377381
}
378382

383+
// Proxy returns 200 when user/pass is provided
384+
379385
url := fmt.Sprintf("http://%s/demo/hello", s.hostIP)
380386
req, err := http.NewRequest("GET", url, nil)
381387
req.SetBasicAuth("admin", "password")
@@ -384,6 +390,21 @@ func (s IntegrationSwarmTestSuite) Test_ServiceAuthentication() {
384390

385391
s.NoError(err)
386392
s.Equal(200, resp.StatusCode, s.getProxyConf())
393+
394+
// Add ignoreAuthorization
395+
396+
params := fmt.Sprintf("serviceName=go-demo&servicePath.1=/demo&port.1=8080&users=admin:password&ignoreAuthorization.1=true")
397+
s.reconfigureService(params)
398+
399+
// Proxy returns 200 when user/pass is NOT provided
400+
401+
resp, err = s.sendHelloRequest()
402+
403+
if err != nil {
404+
s.Fail(err.Error())
405+
} else {
406+
s.Equal(200, resp.StatusCode, s.getProxyConf())
407+
}
387408
}
388409

389410
func (s IntegrationSwarmTestSuite) Test_XTcp() {

proxy/template.go

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,23 +58,24 @@ backend {{$.ServiceName}}-be{{.Port}}
5858
server {{"{{$e.Node}}_{{$i}}_{{$e.Port}} {{$e.Address}}:{{$e.Port}}"}}
5959
{{"{{end}}"}}
6060
{{- end}}
61-
{{- if $.Users}}
61+
{{- if not .IgnoreAuthorization}}
62+
{{- if and ($.Users) (not .IgnoreAuthorization)}}
6263
acl {{$.ServiceName}}UsersAcl http_auth({{$.ServiceName}}Users)
6364
http-request auth realm {{$.ServiceName}}Realm if !{{$.ServiceName}}UsersAcl
64-
{{- end}}
65-
{{- if $.UseGlobalUsers}}
65+
{{- end}}
66+
{{- if $.UseGlobalUsers}}
6667
acl defaultUsersAcl http_auth(defaultUsers)
6768
http-request auth realm defaultRealm if !defaultUsersAcl
68-
{{- end}}
69-
{{- if or ($.Users) ($.UseGlobalUsers)}}
69+
{{- end}}
70+
{{- if or ($.Users) ($.UseGlobalUsers)}}
7071
http-request del-header Authorization
72+
{{- end}}
7173
{{- end}}
7274
{{- end}}
7375
{{- if ne $.BackendExtra ""}}
7476
{{ $.BackendExtra }}
7577
{{- end}}
7678
{{- if gt .HttpsPort 0}}{{range .ServiceDest}}
77-
7879
backend https-{{$.ServiceName}}-be{{.Port}}
7980
mode {{.ReqModeFormatted}}
8081
{{- if ne $.ConnectionMode ""}}
@@ -105,21 +106,18 @@ backend https-{{$.ServiceName}}-be{{.Port}}
105106
server {{"{{$e.Node}}_{{$i}}_{{$e.Port}} {{$e.Address}}:{{$e.Port}}"}}
106107
{{"{{end}}"}}
107108
{{- end}}
108-
{{- if $.Users}}
109+
{{- if not .IgnoreAuthorization}}
110+
{{- if $.Users}}
109111
acl {{$.ServiceName}}UsersAcl http_auth({{$.ServiceName}}Users)
110112
http-request auth realm {{$.ServiceName}}Realm if !{{$.ServiceName}}UsersAcl
111-
http-request del-header Authorization
112-
{{- end}}
113-
{{- if $.Users}}
114-
acl {{$.ServiceName}}UsersAcl http_auth({{$.ServiceName}}Users)
115-
http-request auth realm {{$.ServiceName}}Realm if !{{$.ServiceName}}UsersAcl
116-
{{- end}}
117-
{{- if $.UseGlobalUsers}}
113+
{{- end}}
114+
{{- if $.UseGlobalUsers}}
118115
acl defaultUsersAcl http_auth(defaultUsers)
119116
http-request auth realm defaultRealm if !defaultUsersAcl
120-
{{- end}}
121-
{{- if or ($.Users) ($.UseGlobalUsers)}}
117+
{{- end}}
118+
{{- if or ($.Users) ($.UseGlobalUsers)}}
122119
http-request del-header Authorization
120+
{{- end}}
123121
{{- end}}
124122
{{- end}}
125123
{{- if ne $.BackendExtra ""}}

proxy/types.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ var usersBasePath string = "/run/secrets/dfp_users_%s"
1010

1111
// ServiceDest holds data used to generate proxy configuration. It is extracted as a separate struct since a single service can have multiple combinations.
1212
type ServiceDest struct {
13+
// Whether to ignore authorization for this service destination.
14+
IgnoreAuthorization bool
1315
// The internal port of a service that should be reconfigured.
1416
// The port is used only in the *swarm* mode.
1517
Port string
@@ -348,16 +350,15 @@ func getServiceDest(sr *Service, provider ServiceParameterProvider, index int) S
348350
if len(provider.GetString(fmt.Sprintf("reqMode%s", suffix))) > 0 {
349351
reqMode = provider.GetString(fmt.Sprintf("reqMode%s", suffix))
350352
}
351-
port := provider.GetString(fmt.Sprintf("port%s", suffix))
352353
srcPort, _ := strconv.Atoi(provider.GetString(fmt.Sprintf("srcPort%s", suffix)))
353-
verifyClientSsl := getBoolParam(provider, fmt.Sprintf("verifyClientSsl%s", suffix))
354354
return ServiceDest{
355-
Port: port,
356-
ReqMode: reqMode,
357-
SrcPort: srcPort,
358-
ServicePath: path,
359-
VerifyClientSsl: verifyClientSsl,
360-
UserAgent: userAgent,
355+
IgnoreAuthorization: getBoolParam(provider, fmt.Sprintf("ignoreAuthorization%s", suffix)),
356+
Port: provider.GetString(fmt.Sprintf("port%s", suffix)),
357+
ReqMode: reqMode,
358+
SrcPort: srcPort,
359+
ServicePath: path,
360+
VerifyClientSsl: getBoolParam(provider, fmt.Sprintf("verifyClientSsl%s", suffix)),
361+
UserAgent: userAgent,
361362
}
362363

363364
}

proxy/types_test.go

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,12 @@ func (s *TypesTestSuite) getServiceMap(expected Service, indexSuffix string) map
223223
"usersPassEncrypted": "true",
224224
"xForwardedProto": strconv.FormatBool(expected.XForwardedProto),
225225
// ServiceDest
226-
"port" + indexSuffix: expected.ServiceDest[0].Port,
227-
"reqMode" + indexSuffix: expected.ServiceDest[0].ReqMode,
228-
"servicePath" + indexSuffix: strings.Join(expected.ServiceDest[0].ServicePath, ","),
229-
"userAgent" + indexSuffix: strings.Join(expected.ServiceDest[0].UserAgent.Value, ","),
230-
"verifyClientSsl" + indexSuffix: strconv.FormatBool(expected.ServiceDest[0].VerifyClientSsl),
226+
"ignoreAuthorization" + indexSuffix: strconv.FormatBool(expected.ServiceDest[0].IgnoreAuthorization),
227+
"port" + indexSuffix: expected.ServiceDest[0].Port,
228+
"reqMode" + indexSuffix: expected.ServiceDest[0].ReqMode,
229+
"servicePath" + indexSuffix: strings.Join(expected.ServiceDest[0].ServicePath, ","),
230+
"userAgent" + indexSuffix: strings.Join(expected.ServiceDest[0].UserAgent.Value, ","),
231+
"verifyClientSsl" + indexSuffix: strconv.FormatBool(expected.ServiceDest[0].VerifyClientSsl),
231232
}
232233
}
233234

@@ -251,11 +252,12 @@ func (s *TypesTestSuite) getExpectedService() Service {
251252
ServiceCert: "serviceCert",
252253
ServiceColor: "serviceColor",
253254
ServiceDest: []ServiceDest{{
254-
ServicePath: []string{"/"},
255-
Port: "1234",
256-
ReqMode: "reqMode",
257-
UserAgent: UserAgent{Value: []string{"agent-1", "agent-2/replace-with_"}, AclName: "agent_1_agent_2_replace_with_"},
258-
VerifyClientSsl: true,
255+
IgnoreAuthorization: true,
256+
ServicePath: []string{"/"},
257+
Port: "1234",
258+
ReqMode: "reqMode",
259+
UserAgent: UserAgent{Value: []string{"agent-1", "agent-2/replace-with_"}, AclName: "agent_1_agent_2_replace_with_"},
260+
VerifyClientSsl: true,
259261
}},
260262
ServiceDomain: []string{"domain1", "domain2"},
261263
ServiceDomainMatchAll: true,
@@ -268,7 +270,9 @@ func (s *TypesTestSuite) getExpectedService() Service {
268270
TimeoutServer: "timeoutServer",
269271
TimeoutTunnel: "timeoutTunnel",
270272
XForwardedProto: true,
271-
Users: []User{{Username: "user1", Password: "pass1", PassEncrypted: true},
272-
{Username: "user2", Password: "pass2", PassEncrypted: true}},
273+
Users: []User{
274+
{Username: "user1", Password: "pass1", PassEncrypted: true},
275+
{Username: "user2", Password: "pass2", PassEncrypted: true},
276+
},
273277
}
274278
}

scripts/local-ci.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#!/bin/bash
2+
23
set -e
4+
35
if [[ ( -z ${DOCKER_HUB_USER} ) || ( -z ${HOST_IP} ) ]]; then
46
echo "set DOCKER_HUB_USER variable to your docker hub account, HOST_IP to your host Ip before running"
57
exit 1

0 commit comments

Comments
 (0)