Skip to content

Commit 2774a77

Browse files
committed
Fixes #91
1 parent 5679433 commit 2774a77

File tree

11 files changed

+351
-42
lines changed

11 files changed

+351
-42
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ Docker Flow: Proxy
1818

1919
* [Reconfigure](#reconfigure)
2020
* [Remove](#remove)
21-
* [Config](#config)
2221
* [Put Certificate](#put-certificate)
22+
* [Reload](#reload)
23+
* [Config](#config)
2324

2425
* [Feedback and Contribution](#feedback-and-contribution)
2526

@@ -140,6 +141,12 @@ Please note that the internal proxy port `8080` must be published.
140141

141142
The example would send a certificate stored in the `my-certificate.pem` file. The certificate would be distributed to all replicas of the proxy.
142143

144+
### Reload
145+
146+
> Reloads proxy configuration
147+
148+
The address is **[PROXY_IP]:[PROXY_PORT]/v1/docker-flow-proxy/reload**
149+
143150
### Config
144151

145152
> Outputs HAProxy configuration

actions/reconfigure.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ func (m *Reconfigure) Execute(args []string) error {
105105
if err := proxy.Instance.CreateConfigFromTemplates(); err != nil {
106106
return err
107107
}
108-
if err := proxy.Instance.Reload(); err != nil {
108+
reload := Reload{}
109+
if err := reload.Execute(); err != nil {
109110
return err
110111
}
111112
if len(m.ConsulAddresses) > 0 || !isSwarm(m.ServiceReconfigure.Mode) {
@@ -199,7 +200,8 @@ func (m *Reconfigure) reloadFromRegistry(addresses []string, instanceName, mode
199200
if err := proxy.Instance.CreateConfigFromTemplates(); err != nil {
200201
return err
201202
}
202-
return proxy.Instance.Reload()
203+
reload := Reload{}
204+
return reload.Execute()
203205
}
204206

205207
func (m *Reconfigure) getService(addresses []string, serviceName, instanceName string, c chan ServiceReconfigure) {

actions/reload.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package actions
2+
3+
import "../proxy"
4+
5+
type Reloader interface {
6+
Execute() error
7+
}
8+
9+
type Reload struct {}
10+
11+
func (m *Reload) Execute() error {
12+
if err := proxy.Instance.Reload(); err != nil {
13+
logPrintf(err.Error())
14+
return err
15+
}
16+
return nil
17+
}
18+
19+
var NewReload = func() Reloader {
20+
return &Reload{}
21+
}

actions/reload_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package actions
2+
3+
import (
4+
"github.com/stretchr/testify/suite"
5+
"testing"
6+
"../proxy"
7+
"fmt"
8+
)
9+
10+
type ReloadTestSuite struct {
11+
suite.Suite
12+
}
13+
14+
func TestReloadUnitTestSuite(t *testing.T) {
15+
suite.Run(t, new(ReloadTestSuite))
16+
}
17+
18+
func (s *ReloadTestSuite) SetupTest() {
19+
}
20+
21+
// Execute
22+
23+
func (s *ReloadTestSuite) Test_Execute_Invokes_HaProxyReload() {
24+
proxyOrig := proxy.Instance
25+
defer func() { proxy.Instance = proxyOrig }()
26+
mockObj := getProxyMock("")
27+
proxy.Instance = mockObj
28+
reload := Reload{}
29+
30+
reload.Execute()
31+
32+
mockObj.AssertCalled(s.T(), "Reload")
33+
}
34+
35+
func (s *ReloadTestSuite) Test_Execute_ReturnsError_WhenHaProxyReloadFails() {
36+
proxyOrig := proxy.Instance
37+
defer func() { proxy.Instance = proxyOrig }()
38+
mockObj := getProxyMock("Reload")
39+
mockObj.On("Reload").Return(fmt.Errorf("This is an error"))
40+
proxy.Instance = mockObj
41+
reload := Reload{}
42+
43+
err := reload.Execute()
44+
45+
s.Error(err)
46+
}
47+
48+
// NewReload
49+
50+
func (s *ReloadTestSuite) Test_NewReload_ReturnsNewInstance() {
51+
r := NewReload()
52+
53+
s.NotNil(r)
54+
}

actions/remove.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,12 @@ func (m *Remove) Execute(args []string) error {
4242
logPrintf(err.Error())
4343
return err
4444
}
45-
println("111")
4645
if err := proxy.Instance.CreateConfigFromTemplates(); err != nil {
4746
logPrintf(err.Error())
4847
return err
4948
}
50-
println("222")
51-
if err := proxy.Instance.Reload(); err != nil {
49+
reload := Reload{}
50+
if err := reload.Execute(); err != nil {
5251
logPrintf(err.Error())
5352
return err
5453
}

actions/remove_test.go

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
package actions
44

55
import (
6-
haproxy "../proxy"
6+
"../proxy"
77
"fmt"
88
"github.com/stretchr/testify/mock"
99
"github.com/stretchr/testify/suite"
@@ -20,6 +20,17 @@ type RemoveTestSuite struct {
2020
InstanceName string
2121
}
2222

23+
func TestRemoveUnitTestSuite(t *testing.T) {
24+
registryInstanceOrig := registryInstance
25+
defer func() { registryInstance = registryInstanceOrig }()
26+
registryInstance = getRegistrarableMock("")
27+
logPrintf = func(format string, v ...interface{}) {}
28+
proxyOrig := proxy.Instance
29+
defer func() { proxy.Instance = proxyOrig }()
30+
proxy.Instance = getProxyMock("")
31+
suite.Run(t, new(RemoveTestSuite))
32+
}
33+
2334
func (s *RemoveTestSuite) SetupTest() {
2435
s.ServiceName = "myService"
2536
s.TemplatesPath = "/path/to/templates"
@@ -84,45 +95,45 @@ func (s RemoveTestSuite) Test_Execute_ReturnsError_WhenFailure() {
8495
}
8596

8697
func (s RemoveTestSuite) Test_Execute_Invokes_HaProxyCreateConfigFromTemplates() {
87-
proxyOrig := haproxy.Instance
88-
defer func() { haproxy.Instance = proxyOrig }()
98+
proxyOrig := proxy.Instance
99+
defer func() { proxy.Instance = proxyOrig }()
89100
mockObj := getProxyMock("")
90-
haproxy.Instance = mockObj
101+
proxy.Instance = mockObj
91102

92103
s.remove.Execute([]string{})
93104

94105
mockObj.AssertCalled(s.T(), "CreateConfigFromTemplates")
95106
}
96107

97108
func (s RemoveTestSuite) Test_Execute_ReturnsError_WhenHaProxyCreateConfigFromTemplatesFails() {
98-
proxyOrig := haproxy.Instance
99-
defer func() { haproxy.Instance = proxyOrig }()
109+
proxyOrig := proxy.Instance
110+
defer func() { proxy.Instance = proxyOrig }()
100111
mockObj := getProxyMock("CreateConfigFromTemplates")
101112
mockObj.On("CreateConfigFromTemplates", mock.Anything, mock.Anything).Return(fmt.Errorf("This is an error"))
102-
haproxy.Instance = mockObj
113+
proxy.Instance = mockObj
103114

104115
err := s.remove.Execute([]string{})
105116

106117
s.Error(err)
107118
}
108119

109120
func (s RemoveTestSuite) Test_Execute_Invokes_HaProxyReload() {
110-
proxyOrig := haproxy.Instance
111-
defer func() { haproxy.Instance = proxyOrig }()
121+
proxyOrig := proxy.Instance
122+
defer func() { proxy.Instance = proxyOrig }()
112123
mockObj := getProxyMock("")
113-
haproxy.Instance = mockObj
124+
proxy.Instance = mockObj
114125

115126
s.remove.Execute([]string{})
116127

117128
mockObj.AssertCalled(s.T(), "Reload")
118129
}
119130

120131
func (s RemoveTestSuite) Test_Execute_ReturnsError_WhenHaProxyReloadFails() {
121-
proxyOrig := haproxy.Instance
122-
defer func() { haproxy.Instance = proxyOrig }()
132+
proxyOrig := proxy.Instance
133+
defer func() { proxy.Instance = proxyOrig }()
123134
mockObj := getProxyMock("CreateConfigFromTemplates")
124135
mockObj.On("CreateConfigFromTemplates", mock.Anything, mock.Anything).Return(fmt.Errorf("This is an error"))
125-
haproxy.Instance = mockObj
136+
proxy.Instance = mockObj
126137

127138
err := s.remove.Execute([]string{})
128139

@@ -175,16 +186,3 @@ func (s RemoveTestSuite) Test_Execute_ReturnsError_WhenDeleteRequestToRegistryFa
175186

176187
s.Error(err)
177188
}
178-
179-
// Suite
180-
181-
func TestRemoveUnitTestSuite(t *testing.T) {
182-
registryInstanceOrig := registryInstance
183-
defer func() { registryInstance = registryInstanceOrig }()
184-
registryInstance = getRegistrarableMock("")
185-
logPrintf = func(format string, v ...interface{}) {}
186-
proxyOrig := haproxy.Instance
187-
defer func() { haproxy.Instance = proxyOrig }()
188-
haproxy.Instance = getProxyMock("")
189-
suite.Run(t, new(RemoveTestSuite))
190-
}

integration_tests/integration_test.go

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func (s IntegrationTestSuite) Test_Reconfigure_MultiplePaths() {
5252
s.verifyReconfigure(2)
5353
}
5454

55-
func (s IntegrationTestSuite) Test_Global_Auth() {
55+
func (s IntegrationTestSuite) Test_GlobalAuth() {
5656
s.reconfigure("", "", "", "/v1/test")
5757

5858
// Returns status 401 if no auth is provided
@@ -75,6 +75,55 @@ func (s IntegrationTestSuite) Test_Global_Auth() {
7575
s.Equal(200, resp.StatusCode)
7676
}
7777

78+
func (s IntegrationTestSuite) Test_Reload() {
79+
s.reconfigure("", "", "", "/v1/test")
80+
81+
// Returns status 200
82+
83+
addr := fmt.Sprintf("http://%s/v1/test", os.Getenv("DOCKER_IP"))
84+
log.Printf(">> Sending verify request to %s", addr)
85+
client := &http.Client{}
86+
request, _ := http.NewRequest("GET", addr, nil)
87+
request.SetBasicAuth("user1", "pass1")
88+
resp, err := client.Do(request)
89+
90+
s.NoError(err)
91+
s.Equal(200, resp.StatusCode)
92+
93+
data := []struct {
94+
confFile string
95+
expectedStatus int
96+
}{
97+
{"reload-error.cfg", 503},
98+
{"reload.cfg", 200},
99+
}
100+
101+
for _, d := range data {
102+
cmdString := fmt.Sprintf(
103+
"docker cp /usr/src/myapp/test_configs/%s dockerflowproxy_staging-dep_1:/cfg/haproxy.cfg",
104+
d.confFile,
105+
)
106+
_, err = exec.Command("/bin/sh", "-c", cmdString).Output()
107+
s.NoError(err)
108+
addr = fmt.Sprintf("http://%s:8080/v1/docker-flow-proxy/reload", os.Getenv("DOCKER_IP"))
109+
log.Printf(">> Sending reload request to %s", addr)
110+
request, _ = http.NewRequest("GET", addr, nil)
111+
resp, err = client.Do(request)
112+
113+
s.NoError(err)
114+
s.Equal(200, resp.StatusCode)
115+
116+
addr = fmt.Sprintf("http://%s/v1/test", os.Getenv("DOCKER_IP"))
117+
log.Printf(">> Sending verify request to %s", addr)
118+
request, _ = http.NewRequest("GET", addr, nil)
119+
request.SetBasicAuth("user1", "pass1")
120+
resp, err = client.Do(request)
121+
122+
s.NoError(err)
123+
s.Equal(d.expectedStatus, resp.StatusCode)
124+
}
125+
}
126+
78127
func (s IntegrationTestSuite) Test_Reconfigure_Auth() {
79128
address := fmt.Sprintf(
80129
"http://%s:8080/v1/docker-flow-proxy/reconfigure?serviceName=%s&servicePath=%s&users=%s",

server.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ type Serve struct {
3232

3333
var serverImpl = Serve{}
3434
var cert server.Certer = server.NewCert("/certs")
35+
var reload actions.Reloader = actions.NewReload()
3536

3637
type Response struct {
3738
Status string
@@ -93,12 +94,6 @@ func (m *Serve) ServeHTTP(w http.ResponseWriter, req *http.Request) {
9394
logPrintf("Processing request %s", req.URL)
9495
}
9596
switch req.URL.Path {
96-
case "/v1/docker-flow-proxy/reconfigure":
97-
m.reconfigure(w, req)
98-
case "/v1/docker-flow-proxy/remove":
99-
m.remove(w, req)
100-
case "/v1/docker-flow-proxy/config":
101-
m.config(w, req)
10297
case "/v1/docker-flow-proxy/cert":
10398
if req.Method == "PUT" {
10499
cert.Put(w, req)
@@ -108,12 +103,17 @@ func (m *Serve) ServeHTTP(w http.ResponseWriter, req *http.Request) {
108103
}
109104
case "/v1/docker-flow-proxy/certs":
110105
cert.GetAll(w, req)
106+
case "/v1/docker-flow-proxy/config":
107+
m.config(w, req)
108+
case "/v1/docker-flow-proxy/reconfigure":
109+
m.reconfigure(w, req)
110+
case "/v1/docker-flow-proxy/remove":
111+
m.remove(w, req)
112+
case "/v1/docker-flow-proxy/reload":
113+
reload.Execute()
111114
case "/v1/test", "/v2/test":
112115
js, _ := json.Marshal(Response{Status: "OK"})
113116
httpWriterSetContentType(w, "application/json")
114-
if !strings.EqualFold(req.URL.Path, "/v1/test") {
115-
116-
}
117117
w.WriteHeader(http.StatusOK)
118118
w.Write(js)
119119
default:

server_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,27 @@ func (s *ServerTestSuite) Test_ServeHTTP_InvokesCertGetAll_WhenUrlIsCerts() {
373373
s.Assert().True(invoked)
374374
}
375375

376+
// ServeHTTP > Reload
377+
378+
func (s *ServerTestSuite) Test_ServeHTTP_InvokesReload_WhenUrlIsReload() {
379+
invoked := false
380+
reloadOrig := reload
381+
defer func() { reload = reloadOrig }()
382+
reload = ReloadMock{
383+
ExecuteMock: func() error {
384+
invoked = true
385+
return nil
386+
},
387+
}
388+
url := fmt.Sprintf("%s/reload", s.BaseUrl)
389+
req, _ := http.NewRequest("GET", url, nil)
390+
391+
srv := Serve{}
392+
srv.ServeHTTP(s.ResponseWriter, req)
393+
394+
s.Assert().True(invoked)
395+
}
396+
376397
// ServeHTTP > Reconfigure
377398

378399
func (s *ServerTestSuite) Test_ServeHTTP_SetsContentTypeToJSON_WhenUrlIsReconfigure() {
@@ -991,6 +1012,14 @@ func (m CertMock) Init() error {
9911012
return m.GetInitMock()
9921013
}
9931014

1015+
type ReloadMock struct {
1016+
ExecuteMock func() error
1017+
}
1018+
1019+
func (m ReloadMock) Execute() error {
1020+
return m.ExecuteMock()
1021+
}
1022+
9941023
type RunMock struct {
9951024
mock.Mock
9961025
}

0 commit comments

Comments
 (0)