Skip to content

Commit

Permalink
Merge pull request #58 from nicholasjackson/dev
Browse files Browse the repository at this point in the history
Fix release reconfigure bug
  • Loading branch information
nicholasjackson authored Mar 14, 2022
2 parents 6d3e2e7 + ee4346b commit f1503bf
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 15 deletions.
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.0.14 - 2022-03-14
### Fixed
- Ensure a release reconfigures the plugins on update

## [0.0.11 - 2022-03-08
### Changed
- Updated Kubernetes deployment health timeout to 10 minutes from 1 minute.
Expand Down
15 changes: 13 additions & 2 deletions plugins/mocks/mocks.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mocks

import (
"bytes"
"testing"
"time"

Expand All @@ -19,6 +20,7 @@ type Mocks struct {
StoreMock *StoreMock
StateMachineMock *StateMachineMock
WebhookMock *WebhookMock
LogBuffer *bytes.Buffer
}

// BuildMocks builds a mock provider and mock plugins for testing
Expand Down Expand Up @@ -80,13 +82,22 @@ func BuildMocks(t *testing.T) (*ProviderMock, *Mocks) {
provMock.On("CreateStrategy", mock.Anything).Return(stratMock, nil)
provMock.On("CreateWebhook", mock.Anything).Return(webhookMock, nil)

provMock.On("GetLogger", mock.Anything).Return(hclog.New(&hclog.LoggerOptions{Color: hclog.AutoColor, Level: hclog.Debug}))
logBuffer := bytes.NewBufferString("")

logger := hclog.New(
&hclog.LoggerOptions{
Level: hclog.Trace,
Output: logBuffer,
},
)

provMock.On("GetLogger", mock.Anything).Return(logger)
provMock.On("GetMetrics").Return(metricsMock)
provMock.On("GetDataStore").Return(storeMock)
provMock.On("GetStateMachine", mock.Anything).Return(stateMock, nil)
provMock.On("DeleteStateMachine", mock.Anything).Return(nil)

return provMock, &Mocks{relMock, runMock, monMock, stratMock, metricsMock, storeMock, stateMock, webhookMock}
return provMock, &Mocks{relMock, runMock, monMock, stratMock, metricsMock, storeMock, stateMock, webhookMock, logBuffer}
}

// ProviderMock is a mock implementation of the provider that can be used for testing
Expand Down
25 changes: 12 additions & 13 deletions plugins/statemachine/statemachine.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,8 @@ func (s *StateMachine) doConfigure() func(e *fsm.Event) {
if err != nil {
s.logger.Error("Configure completed with error", "error", err)

e.FSM.Event(interfaces.EventFail)

s.callWebhooks(s.webhookPlugins, "Configure release failed", interfaces.StateConfigure, interfaces.EventFail, 0, 100, err)
e.FSM.Event(interfaces.EventFail)
return
}

Expand Down Expand Up @@ -494,8 +493,8 @@ func (s *StateMachine) doPromote() func(e *fsm.Event) {
// scale all traffic to the candidate before promoting
err := s.releaserPlugin.Scale(ctx, 100)
if err != nil {
e.FSM.Event(interfaces.EventFail)
s.callWebhooks(s.webhookPlugins, "Promoting candidate failed", interfaces.StatePromote, interfaces.EventFail, 0, 100, err)
e.FSM.Event(interfaces.EventFail)
return
}

Expand All @@ -511,25 +510,25 @@ func (s *StateMachine) doPromote() func(e *fsm.Event) {
// promote the candidate to primary
_, err = s.runtimePlugin.PromoteCandidate(ctx)
if err != nil {
e.FSM.Event(interfaces.EventFail)
s.callWebhooks(s.webhookPlugins, "Promoting candidate failed", interfaces.StatePromote, interfaces.EventFail, 0, 100, err)
e.FSM.Event(interfaces.EventFail)
return
}

err = s.releaserPlugin.WaitUntilServiceHealthy(ctx, interfaces.Primary)
if err != nil {
s.logger.Error("Configure completed with error", "error", err)

e.FSM.Event(interfaces.EventFail)
s.callWebhooks(s.webhookPlugins, "Promoting candidate failed", interfaces.StatePromote, interfaces.EventFail, 0, 100, err)
e.FSM.Event(interfaces.EventFail)
return
}

// scale all traffic to the primary
err = s.releaserPlugin.Scale(ctx, 0)
if err != nil {
e.FSM.Event(interfaces.EventFail)
s.callWebhooks(s.webhookPlugins, "Promoting candidate failed", interfaces.StatePromote, interfaces.EventFail, 0, 100, err)
e.FSM.Event(interfaces.EventFail)
return
}

Expand All @@ -538,8 +537,8 @@ func (s *StateMachine) doPromote() func(e *fsm.Event) {
// scale down the canary
err = s.runtimePlugin.RemoveCandidate(ctx)
if err != nil {
e.FSM.Event(interfaces.EventFail)
s.callWebhooks(s.webhookPlugins, "Promoting candidate failed", interfaces.StatePromote, interfaces.EventFail, 100, 0, err)
e.FSM.Event(interfaces.EventFail)
return
}

Expand Down Expand Up @@ -587,8 +586,8 @@ func (s *StateMachine) doRollback() func(e *fsm.Event) {
// scale down the canary
err = s.runtimePlugin.RemoveCandidate(ctx)
if err != nil {
e.FSM.Event(interfaces.EventFail)
s.callWebhooks(s.webhookPlugins, "Rolling back deployment failed", interfaces.StateRollback, interfaces.EventFail, 100, 0, err)
e.FSM.Event(interfaces.EventFail)
return
}

Expand All @@ -609,8 +608,8 @@ func (s *StateMachine) doDestroy() func(e *fsm.Event) {
// restore the original deployment
err := s.runtimePlugin.RestoreOriginal(ctx)
if err != nil {
e.FSM.Event(interfaces.EventFail)
s.callWebhooks(s.webhookPlugins, "Remove release failed", interfaces.StateDestroy, interfaces.EventFail, 100, 0, err)
e.FSM.Event(interfaces.EventFail)
return
}

Expand All @@ -619,16 +618,16 @@ func (s *StateMachine) doDestroy() func(e *fsm.Event) {
if err != nil {
s.logger.Error("Configure completed with error", "error", err)

e.FSM.Event(interfaces.EventFail)
s.callWebhooks(s.webhookPlugins, "Remove release failed", interfaces.StateDestroy, interfaces.EventFail, 100, 0, err)
e.FSM.Event(interfaces.EventFail)
return
}

// scale all traffic to the candidate
err = s.releaserPlugin.Scale(ctx, 100)
if err != nil {
e.FSM.Event(interfaces.EventFail)
s.callWebhooks(s.webhookPlugins, "Remove release failed", interfaces.StateDestroy, interfaces.EventFail, 100, 0, err)
e.FSM.Event(interfaces.EventFail)
return
}

Expand All @@ -644,16 +643,16 @@ func (s *StateMachine) doDestroy() func(e *fsm.Event) {
// destroy the primary
err = s.runtimePlugin.RemovePrimary(ctx)
if err != nil {
e.FSM.Event(interfaces.EventFail)
s.callWebhooks(s.webhookPlugins, "Remove release failed", interfaces.StateDestroy, interfaces.EventFail, 0, 100, err)
e.FSM.Event(interfaces.EventFail)
return
}

// remove the consul config
err = s.releaserPlugin.Destroy(ctx)
if err != nil {
e.FSM.Event(interfaces.EventFail)
s.callWebhooks(s.webhookPlugins, "Remove release failed", interfaces.StateDestroy, interfaces.EventFail, 0, 100, err)
e.FSM.Event(interfaces.EventFail)
return
}

Expand Down
6 changes: 6 additions & 0 deletions plugins/statemachine/statemachine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ func setupTests(t *testing.T) (*models.Release, *StateMachine, *mocks.Mocks) {
pp.AssertCalled(t, "CreateWebhook", r.Webhooks[0].Name)
pm.WebhookMock.AssertCalled(t, "Configure", r.Webhooks[0].Config)

t.Cleanup(func() {
if t.Failed() {
fmt.Println(pm.LogBuffer.String())
}
})

return r, sm, pm
}

Expand Down

0 comments on commit f1503bf

Please sign in to comment.