Skip to content

Commit c8d1276

Browse files
brianterrysthulb
authored andcommitted
Fix callback (#95)
* Remove repeated code. * Updates build tag location * Adds helper methods * Adds callback status * Update test * Remove pending status from handler * Adds cfn test * MockScheduler * Update test to use func as value * Add create test data * Adds publisher no tag option * Adds no client to no tag publisher * Adds no op * Adds no op * Adds no tag option to scheduler * Fix publisher build tag * Fix publisher build tag * Fixed typo * Added mocked context * Adds error testing * Adds invaild action * Adds invaild action * Updates Makefile * Adds reportErr * Adds reportErr * Updated logging * Addslogger * Fix logging * Updates testing
1 parent b3967c7 commit c8d1276

File tree

20 files changed

+1018
-185
lines changed

20 files changed

+1018
-185
lines changed

cfn/callback/callback.go

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,31 +20,58 @@ import (
2020
)
2121

2222
const (
23-
//ServiceInternalError ...
23+
// ServiceInternalError ...
2424
ServiceInternalError string = "ServiceInternal"
25-
//MaxRetries is the number of retries allowed to report status.
25+
// MaxRetries is the number of retries allowed to report status.
2626
MaxRetries uint = 3
2727
)
2828

29-
//CloudFormationCallbackAdapter used to report progress events back to CloudFormation.
29+
// CloudFormationCallbackAdapter used to report progress events back to CloudFormation.
3030
type CloudFormationCallbackAdapter struct {
31-
logger *log.Logger
32-
client cloudformationiface.CloudFormationAPI
31+
client cloudformationiface.CloudFormationAPI
32+
bearerToken string
33+
logger *log.Logger
3334
}
3435

35-
//New creates a CloudFormationCallbackAdapter and returns a pointer to the struct.
36-
func New(client cloudformationiface.CloudFormationAPI) *CloudFormationCallbackAdapter {
36+
// New creates a CloudFormationCallbackAdapter and returns a pointer to the struct.
37+
func New(client cloudformationiface.CloudFormationAPI, bearerToken string) *CloudFormationCallbackAdapter {
3738
return &CloudFormationCallbackAdapter{
38-
logger: logging.New("callback: "),
39-
client: client,
39+
client: client,
40+
bearerToken: bearerToken,
41+
logger: logging.New("callback"),
4042
}
4143
}
4244

43-
//ReportProgress reports the current status back to the Cloudformation service.
44-
func (c *CloudFormationCallbackAdapter) ReportProgress(bearerToken string, code string, operationStatus string, currentOperationStatus string, resourceModel string, statusMessage string) error {
45+
// ReportStatus reports the status back to the Cloudformation service of a handler
46+
// that has moved from Pending to In_Progress
47+
func (c *CloudFormationCallbackAdapter) ReportStatus(operationStatus Status, model []byte, message string, errCode string) error {
48+
if err := c.reportProgress(errCode, operationStatus, InProgress, model, message); err != nil {
49+
return err
50+
}
51+
return nil
52+
}
53+
54+
// ReportInitialStatus reports the initial status back to the Cloudformation service.
55+
func (c *CloudFormationCallbackAdapter) ReportInitialStatus() error {
56+
if err := c.reportProgress("", InProgress, Pending, []byte(""), ""); err != nil {
57+
return err
58+
}
59+
return nil
60+
}
61+
62+
//ReportFailureStatus reports the failure status back to the Cloudformation service.
63+
func (c *CloudFormationCallbackAdapter) ReportFailureStatus(model []byte, errCode string, handlerError error) error {
64+
if err := c.reportProgress(errCode, Failed, InProgress, model, handlerError.Error()); err != nil {
65+
return err
66+
}
67+
return nil
68+
}
69+
70+
// ReportProgress reports the current status back to the Cloudformation service.
71+
func (c *CloudFormationCallbackAdapter) reportProgress(errCode string, operationStatus Status, currentOperationStatus Status, resourceModel []byte, statusMessage string) error {
4572

4673
in := cloudformation.RecordHandlerProgressInput{
47-
BearerToken: aws.String(bearerToken),
74+
BearerToken: aws.String(c.bearerToken),
4875
OperationStatus: aws.String(TranslateOperationStatus(operationStatus)),
4976
}
5077

@@ -53,15 +80,15 @@ func (c *CloudFormationCallbackAdapter) ReportProgress(bearerToken string, code
5380
}
5481

5582
if len(resourceModel) != 0 {
56-
in.SetResourceModel(resourceModel)
83+
in.SetResourceModel(string(resourceModel))
5784
}
5885

59-
if len(code) != 0 {
60-
in.SetErrorCode(TranslateErrorCode(code))
86+
if len(errCode) != 0 {
87+
in.SetErrorCode(TranslateErrorCode(errCode))
6188
}
6289

6390
if len(currentOperationStatus) != 0 {
64-
in.SetCurrentOperationStatus(currentOperationStatus)
91+
in.SetCurrentOperationStatus(TranslateOperationStatus(currentOperationStatus))
6592
}
6693

6794
// Do retries and emit logs.
@@ -86,7 +113,7 @@ func (c *CloudFormationCallbackAdapter) ReportProgress(bearerToken string, code
86113
return nil
87114
}
88115

89-
//TranslateErrorCode : Translate the error code into a standard Cloudformation error
116+
// TranslateErrorCode : Translate the error code into a standard Cloudformation error
90117
func TranslateErrorCode(errorCode string) string {
91118

92119
switch errorCode {
@@ -124,16 +151,18 @@ func TranslateErrorCode(errorCode string) string {
124151
}
125152
}
126153

127-
//TranslateOperationStatus Translate the operation Status into a standard Cloudformation error
128-
func TranslateOperationStatus(operationStatus string) string {
154+
// TranslateOperationStatus Translate the operation Status into a standard Cloudformation error
155+
func TranslateOperationStatus(operationStatus Status) string {
129156

130157
switch operationStatus {
131-
case "SUCCESS":
158+
case Success:
132159
return cloudformation.OperationStatusSuccess
133-
case "FAILED":
160+
case Failed:
134161
return cloudformation.OperationStatusFailed
135-
case "IN_PROGRESS":
162+
case InProgress:
136163
return cloudformation.OperationStatusInProgress
164+
case Pending:
165+
return cloudformation.OperationStatusPending
137166
default:
138167
// default will be to fail on unknown status
139168
return cloudformation.OperationStatusFailed

cfn/callback/callback_notag.go

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,52 @@ import (
1111
"github.com/aws/aws-sdk-go/service/cloudformation/cloudformationiface"
1212
)
1313

14-
//CloudFormationCallbackAdapter used to report progress events back to CloudFormation.
14+
// CloudFormationCallbackAdapter used to report progress events back to CloudFormation.
1515
type CloudFormationCallbackAdapter struct {
16-
logger *log.Logger
17-
client cloudformationiface.CloudFormationAPI
16+
logger *log.Logger
17+
client cloudformationiface.CloudFormationAPI
18+
bearerToken string
1819
}
1920

20-
//New creates a CloudFormationCallbackAdapter and returns a pointer to the struct.
21-
func New(client cloudformationiface.CloudFormationAPI) *CloudFormationCallbackAdapter {
21+
// New creates a CloudFormationCallbackAdapter and returns a pointer to the struct.
22+
func New(client cloudformationiface.CloudFormationAPI, bearerToken string) *CloudFormationCallbackAdapter {
2223
return &CloudFormationCallbackAdapter{
23-
logger: logging.New("callback: "),
24-
client: client,
24+
client: client,
25+
bearerToken: bearerToken,
26+
logger: logging.New("callback"),
2527
}
2628
}
2729

28-
//ReportProgress reports the current status back to the Cloudformation service.
29-
func (c *CloudFormationCallbackAdapter) ReportProgress(bearerToken string, code string, operationStatus string, currentOperationStatus string, resourceModel string, statusMessage string) error {
30+
// ReportStatus reports the status back to the Cloudformation service of a handler
31+
// that has moved from Pending to In_Progress
32+
func (c *CloudFormationCallbackAdapter) ReportStatus(operationStatus Status, model []byte, message string, errCode string) error {
33+
if err := c.reportProgress(errCode, operationStatus, InProgress, model, message); err != nil {
34+
return err
35+
}
36+
return nil
37+
}
38+
39+
// ReportInitialStatus reports the initial status back to the Cloudformation service.
40+
func (c *CloudFormationCallbackAdapter) ReportInitialStatus() error {
41+
if err := c.reportProgress("", InProgress, Pending, []byte(""), ""); err != nil {
42+
return err
43+
}
44+
return nil
45+
}
46+
47+
// ReportFailureStatus reports the failure status back to the Cloudformation service.
48+
func (c *CloudFormationCallbackAdapter) ReportFailureStatus(model []byte, errCode string, handlerError error) error {
49+
if err := c.reportProgress(errCode, Failed, InProgress, model, handlerError.Error()); err != nil {
50+
return err
51+
}
52+
return nil
53+
}
54+
55+
// ReportProgress reports the current status back to the Cloudformation service.
56+
func (c *CloudFormationCallbackAdapter) reportProgress(code string, operationStatus Status, currentOperationStatus Status, resourceModel []byte, statusMessage string) error {
3057

3158
in := cloudformation.RecordHandlerProgressInput{
32-
BearerToken: aws.String(bearerToken),
59+
BearerToken: aws.String(c.bearerToken),
3360
OperationStatus: aws.String(TranslateOperationStatus(operationStatus)),
3461
}
3562

@@ -38,23 +65,23 @@ func (c *CloudFormationCallbackAdapter) ReportProgress(bearerToken string, code
3865
}
3966

4067
if len(resourceModel) != 0 {
41-
in.SetResourceModel(resourceModel)
68+
in.SetResourceModel(string(resourceModel))
4269
}
4370

4471
if len(code) != 0 {
4572
in.SetErrorCode(TranslateErrorCode(code))
4673
}
4774

4875
if len(currentOperationStatus) != 0 {
49-
in.SetCurrentOperationStatus(currentOperationStatus)
76+
in.SetCurrentOperationStatus(string(currentOperationStatus))
5077
}
5178

5279
c.logger.Printf("Record progress: %v", &in)
5380

5481
return nil
5582
}
5683

57-
//TranslateErrorCode : Translate the error code into a standard Cloudformation error
84+
// TranslateErrorCode : Translate the error code into a standard Cloudformation error
5885
func TranslateErrorCode(errorCode string) string {
5986

6087
switch errorCode {
@@ -92,16 +119,18 @@ func TranslateErrorCode(errorCode string) string {
92119
}
93120
}
94121

95-
//TranslateOperationStatus Translate the operation Status into a standard Cloudformation error
96-
func TranslateOperationStatus(operationStatus string) string {
122+
// TranslateOperationStatus Translate the operation Status into a standard Cloudformation error
123+
func TranslateOperationStatus(operationStatus Status) string {
97124

98125
switch operationStatus {
99-
case "SUCCESS":
126+
case Success:
100127
return cloudformation.OperationStatusSuccess
101-
case "FAILED":
128+
case Failed:
102129
return cloudformation.OperationStatusFailed
103-
case "IN_PROGRESS":
130+
case InProgress:
104131
return cloudformation.OperationStatusInProgress
132+
case Pending:
133+
return cloudformation.OperationStatusPending
105134
default:
106135
// default will be to fail on unknown status
107136
return cloudformation.OperationStatusFailed

cfn/callback/callback_test.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import (
99
"github.com/aws/aws-sdk-go/service/cloudformation/cloudformationiface"
1010
)
1111

12-
const MockModel string = "{\"foo\": \"bar\"}"
12+
var MockModel = []byte("{\"foo\": \"bar\"}")
1313

14-
//MockedEvents mocks the call to AWS CloudWatch Events
14+
// MockedEvents mocks the call to AWS CloudWatch Events
1515
type MockedCallback struct {
1616
cloudformationiface.CloudFormationAPI
1717
errCount int
@@ -35,7 +35,7 @@ func (m *MockedCallback) RecordHandlerProgress(in *cloudformation.RecordHandlerP
3535

3636
func TestTranslateOperationStatus(t *testing.T) {
3737
type args struct {
38-
operationStatus string
38+
operationStatus Status
3939
}
4040
tests := []struct {
4141
name string
@@ -89,16 +89,16 @@ func TestTranslateErrorCode(t *testing.T) {
8989
}
9090
}
9191

92-
func TestCloudFormationCallbackAdapter_ReportProgress(t *testing.T) {
92+
func TestCloudFormationCallbackAdapterReportProgress(t *testing.T) {
9393
type fields struct {
9494
client cloudformationiface.CloudFormationAPI
9595
}
9696
type args struct {
9797
bearerToken string
9898
code string
99-
status string
100-
operationStatus string
101-
resourceModel string
99+
status Status
100+
operationStatus Status
101+
resourceModel []byte
102102
statusMessage string
103103
}
104104
tests := []struct {
@@ -112,10 +112,11 @@ func TestCloudFormationCallbackAdapter_ReportProgress(t *testing.T) {
112112
for _, tt := range tests {
113113
t.Run(tt.name, func(t *testing.T) {
114114
c := &CloudFormationCallbackAdapter{
115-
client: tt.fields.client,
116-
logger: logging.New("callback: "),
115+
client: tt.fields.client,
116+
logger: logging.New("callback: "),
117+
bearerToken: tt.args.bearerToken,
117118
}
118-
if err := c.ReportProgress(tt.args.bearerToken, tt.args.code, tt.args.status, tt.args.operationStatus, tt.args.resourceModel, tt.args.statusMessage); (err != nil) != tt.wantErr {
119+
if err := c.reportProgress(tt.args.code, tt.args.status, tt.args.operationStatus, tt.args.resourceModel, tt.args.statusMessage); (err != nil) != tt.wantErr {
119120
t.Errorf("CloudFormationCallbackAdapter.ReportProgress() error = %v, wantErr %v", err, tt.wantErr)
120121
}
121122
})

cfn/callback/status.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package callback
2+
3+
//Status represents the status of the handler during invocation.
4+
type Status string
5+
6+
const (
7+
// UnknownStatus represents all states that aren't covered
8+
// elsewhere.
9+
UnknownStatus Status = "UNKNOWN"
10+
11+
// InProgress is when a resource provider
12+
// is in the process of being operated on.
13+
InProgress Status = "IN_PROGRESS"
14+
15+
// Success is when the resource provider
16+
// has finished it's operation.
17+
Success Status = "SUCCESS"
18+
19+
// Failed is when the resource provider
20+
// has failed.
21+
Failed Status = "FAILED"
22+
23+
// Pending is the resource provider
24+
// initial state.
25+
Pending Status = "PENDING"
26+
)

0 commit comments

Comments
 (0)