Skip to content

Commit b62efc1

Browse files
Merge pull request #155 from die-van-de-boekhouding/prevent-saving-invalid-state-on-deploy
Prevent saving invalid configuration on deploy
2 parents 0180240 + 28deaa4 commit b62efc1

File tree

2 files changed

+41
-16
lines changed

2 files changed

+41
-16
lines changed

internal/server/router_test.go

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package server
22

33
import (
4+
"encoding/json"
45
"net/http"
56
"net/http/httptest"
7+
"os"
68
"path/filepath"
79
"strings"
810
"testing"
@@ -207,7 +209,7 @@ func TestRouter_UpdatingOptions(t *testing.T) {
207209
assert.Empty(t, body)
208210
}
209211

210-
func TestRouter_DeploymmentsWithErrorsDoNotUpdateService(t *testing.T) {
212+
func TestRouter_DeploymentsWithErrorsDoNotUpdateService(t *testing.T) {
211213
router := testRouter(t)
212214
_, target := testBackend(t, "first", http.StatusOK)
213215

@@ -220,21 +222,43 @@ func TestRouter_DeploymmentsWithErrorsDoNotUpdateService(t *testing.T) {
220222
serviceOptions := defaultServiceOptions
221223
serviceOptions.Hosts = []string{"example.com"}
222224

225+
assert.NoFileExists(t, router.statePath)
223226
require.NoError(t, router.DeployService("service1", []string{target}, defaultEmptyReaders, serviceOptions, defaultTargetOptions, DefaultDeployTimeout, DefaultDrainTimeout))
224227
ensureServiceIsHealthy()
228+
require.FileExists(t, router.statePath)
229+
230+
ensureStateWasNotSaved := func() {
231+
f, err := os.OpenFile(router.statePath, os.O_RDONLY, 0600)
232+
require.NoError(t, err)
233+
234+
var services []*Service
235+
require.NoError(t, json.NewDecoder(f).Decode(&services), "if this test failed it means an invalid config prevents the system from booting")
236+
237+
sm := NewServiceMap()
238+
for _, service := range services {
239+
sm.Set(service)
240+
}
241+
persistedOptions := sm.Get("service1").options
242+
assert.Equal(t, serviceOptions.TLSPrivateKeyPath, persistedOptions.TLSPrivateKeyPath)
243+
assert.Equal(t, serviceOptions.TLSCertificatePath, persistedOptions.TLSCertificatePath)
244+
assert.Equal(t, serviceOptions.TLSEnabled, persistedOptions.TLSEnabled)
245+
assert.Equal(t, serviceOptions.ErrorPagePath, persistedOptions.ErrorPagePath)
246+
}
225247

226248
t.Run("custom TLS that is not valid", func(t *testing.T) {
227-
serviceOptions := ServiceOptions{TLSEnabled: true, TLSCertificatePath: "not valid", TLSPrivateKeyPath: "not valid"}
228-
require.Error(t, router.DeployService("service1", []string{target}, defaultEmptyReaders, serviceOptions, defaultTargetOptions, DefaultDeployTimeout, DefaultDrainTimeout))
249+
newServiceOptions := ServiceOptions{TLSEnabled: true, TLSCertificatePath: "not valid", TLSPrivateKeyPath: "not valid"}
250+
require.Error(t, router.DeployService("service1", []string{target}, defaultEmptyReaders, newServiceOptions, defaultTargetOptions, DefaultDeployTimeout, DefaultDrainTimeout))
229251

230252
ensureServiceIsHealthy()
253+
ensureStateWasNotSaved()
231254
})
232255

233256
t.Run("custom error pages that are not valid", func(t *testing.T) {
234-
serviceOptions := ServiceOptions{ErrorPagePath: "not valid"}
235-
require.Error(t, router.DeployService("service1", []string{target}, defaultEmptyReaders, serviceOptions, defaultTargetOptions, DefaultDeployTimeout, DefaultDrainTimeout))
257+
newServiceOptions := ServiceOptions{ErrorPagePath: "not valid"}
258+
require.Error(t, router.DeployService("service1", []string{target}, defaultEmptyReaders, newServiceOptions, defaultTargetOptions, DefaultDeployTimeout, DefaultDrainTimeout))
236259

237260
ensureServiceIsHealthy()
261+
ensureStateWasNotSaved()
238262
})
239263
}
240264

internal/server/service.go

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -134,19 +134,20 @@ type Service struct {
134134
func NewService(name string, options ServiceOptions, targetOptions TargetOptions) (*Service, error) {
135135
service := &Service{
136136
name: name,
137-
options: options,
138137
targetOptions: targetOptions,
139138
pauseController: NewPauseController(),
140139
}
141140

142-
return service, service.initialize()
141+
if err := service.initialize(options); err != nil {
142+
return nil, err
143+
}
144+
return service, nil
143145
}
144146

145147
func (s *Service) UpdateOptions(options ServiceOptions, targetOptions TargetOptions) error {
146-
s.options = options
147148
s.targetOptions = targetOptions
148149

149-
return s.initialize()
150+
return s.initialize(options)
150151
}
151152

152153
func (s *Service) Dispose() {
@@ -265,26 +266,25 @@ func (s *Service) UnmarshalJSON(data []byte) error {
265266
s.name = ms.Name
266267
s.pauseController = ms.PauseController
267268
s.rolloutController = ms.RolloutController
268-
s.options = ms.Options
269269
s.targetOptions = ms.TargetOptions
270270

271271
activeTargets, err := NewTargetList(ms.ActiveTargets, ms.ActiveReaders, ms.TargetOptions)
272272
if err != nil {
273273
return err
274274
}
275-
s.active = NewLoadBalancer(activeTargets, s.options.WriterAffinityTimeout, s.options.ReadTargetsAcceptWebsockets)
275+
s.active = NewLoadBalancer(activeTargets, ms.Options.WriterAffinityTimeout, ms.Options.ReadTargetsAcceptWebsockets)
276276
s.active.MarkAllHealthy()
277277

278278
rolloutTargets, err := NewTargetList(ms.RolloutTargets, ms.RolloutReaders, ms.TargetOptions)
279279
if err != nil {
280280
return err
281281
}
282282
if len(rolloutTargets) > 0 {
283-
s.rollout = NewLoadBalancer(rolloutTargets, s.options.WriterAffinityTimeout, s.options.ReadTargetsAcceptWebsockets)
283+
s.rollout = NewLoadBalancer(rolloutTargets, ms.Options.WriterAffinityTimeout, ms.Options.ReadTargetsAcceptWebsockets)
284284
s.rollout.MarkAllHealthy()
285285
}
286286

287-
return s.initialize()
287+
return s.initialize(ms.Options)
288288
}
289289

290290
func (s *Service) Stop(drainTimeout time.Duration, message string) error {
@@ -325,17 +325,18 @@ func (s *Service) Resume() error {
325325

326326
// Private
327327

328-
func (s *Service) initialize() error {
329-
certManager, err := s.createCertManager(s.options)
328+
func (s *Service) initialize(options ServiceOptions) error {
329+
certManager, err := s.createCertManager(options)
330330
if err != nil {
331331
return err
332332
}
333333

334-
middleware, err := s.createMiddleware(s.options, certManager)
334+
middleware, err := s.createMiddleware(options, certManager)
335335
if err != nil {
336336
return err
337337
}
338338

339+
s.options = options
339340
s.certManager = certManager
340341
s.middleware = middleware
341342

0 commit comments

Comments
 (0)