-
Notifications
You must be signed in to change notification settings - Fork 848
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(notifications): add json template (#1542)
- Loading branch information
Showing
5 changed files
with
211 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package notifications | ||
|
||
import ( | ||
"encoding/json" | ||
|
||
t "github.com/containrrr/watchtower/pkg/types" | ||
) | ||
|
||
type jsonMap = map[string]interface{} | ||
|
||
// MarshalJSON implements json.Marshaler | ||
func (d Data) MarshalJSON() ([]byte, error) { | ||
var entries = make([]jsonMap, len(d.Entries)) | ||
for i, entry := range d.Entries { | ||
entries[i] = jsonMap{ | ||
`level`: entry.Level, | ||
`message`: entry.Message, | ||
`data`: entry.Data, | ||
`time`: entry.Time, | ||
} | ||
} | ||
|
||
var report jsonMap | ||
if d.Report != nil { | ||
report = jsonMap{ | ||
`scanned`: marshalReports(d.Report.Scanned()), | ||
`updated`: marshalReports(d.Report.Updated()), | ||
`failed`: marshalReports(d.Report.Failed()), | ||
`skipped`: marshalReports(d.Report.Skipped()), | ||
`stale`: marshalReports(d.Report.Stale()), | ||
`fresh`: marshalReports(d.Report.Fresh()), | ||
} | ||
} | ||
|
||
return json.Marshal(jsonMap{ | ||
`report`: report, | ||
`title`: d.Title, | ||
`host`: d.Host, | ||
`entries`: entries, | ||
}) | ||
} | ||
|
||
func marshalReports(reports []t.ContainerReport) []jsonMap { | ||
jsonReports := make([]jsonMap, len(reports)) | ||
for i, report := range reports { | ||
jsonReports[i] = jsonMap{ | ||
`id`: report.ID().ShortID(), | ||
`name`: report.Name(), | ||
`currentImageId`: report.CurrentImageID().ShortID(), | ||
`latestImageId`: report.LatestImageID().ShortID(), | ||
`imageName`: report.ImageName(), | ||
`state`: report.State(), | ||
} | ||
if errorMessage := report.Error(); errorMessage != "" { | ||
jsonReports[i][`error`] = errorMessage | ||
} | ||
} | ||
return jsonReports | ||
} | ||
|
||
var _ json.Marshaler = &Data{} | ||
|
||
func toJSON(v interface{}) string { | ||
var bytes []byte | ||
var err error | ||
if bytes, err = json.MarshalIndent(v, "", " "); err != nil { | ||
LocalLog.Errorf("failed to marshal JSON in notification template: %v", err) | ||
return "" | ||
} | ||
return string(bytes) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package notifications | ||
|
||
import ( | ||
s "github.com/containrrr/watchtower/pkg/session" | ||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
var _ = Describe("JSON template", func() { | ||
When("using report templates", func() { | ||
When("JSON template is used", func() { | ||
It("should format the messages to the expected format", func() { | ||
expected := `{ | ||
"entries": [ | ||
{ | ||
"data": null, | ||
"level": "info", | ||
"message": "foo Bar", | ||
"time": "0001-01-01T00:00:00Z" | ||
} | ||
], | ||
"host": "Mock", | ||
"report": { | ||
"failed": [ | ||
{ | ||
"currentImageId": "01d210000000", | ||
"error": "accidentally the whole container", | ||
"id": "c79210000000", | ||
"imageName": "mock/fail1:latest", | ||
"latestImageId": "d0a210000000", | ||
"name": "fail1", | ||
"state": "Failed" | ||
} | ||
], | ||
"fresh": [ | ||
{ | ||
"currentImageId": "01d310000000", | ||
"id": "c79310000000", | ||
"imageName": "mock/frsh1:latest", | ||
"latestImageId": "01d310000000", | ||
"name": "frsh1", | ||
"state": "Fresh" | ||
} | ||
], | ||
"scanned": [ | ||
{ | ||
"currentImageId": "01d110000000", | ||
"id": "c79110000000", | ||
"imageName": "mock/updt1:latest", | ||
"latestImageId": "d0a110000000", | ||
"name": "updt1", | ||
"state": "Updated" | ||
}, | ||
{ | ||
"currentImageId": "01d120000000", | ||
"id": "c79120000000", | ||
"imageName": "mock/updt2:latest", | ||
"latestImageId": "d0a120000000", | ||
"name": "updt2", | ||
"state": "Updated" | ||
}, | ||
{ | ||
"currentImageId": "01d210000000", | ||
"error": "accidentally the whole container", | ||
"id": "c79210000000", | ||
"imageName": "mock/fail1:latest", | ||
"latestImageId": "d0a210000000", | ||
"name": "fail1", | ||
"state": "Failed" | ||
}, | ||
{ | ||
"currentImageId": "01d310000000", | ||
"id": "c79310000000", | ||
"imageName": "mock/frsh1:latest", | ||
"latestImageId": "01d310000000", | ||
"name": "frsh1", | ||
"state": "Fresh" | ||
} | ||
], | ||
"skipped": [ | ||
{ | ||
"currentImageId": "01d410000000", | ||
"error": "unpossible", | ||
"id": "c79410000000", | ||
"imageName": "mock/skip1:latest", | ||
"latestImageId": "01d410000000", | ||
"name": "skip1", | ||
"state": "Skipped" | ||
} | ||
], | ||
"stale": [], | ||
"updated": [ | ||
{ | ||
"currentImageId": "01d110000000", | ||
"id": "c79110000000", | ||
"imageName": "mock/updt1:latest", | ||
"latestImageId": "d0a110000000", | ||
"name": "updt1", | ||
"state": "Updated" | ||
}, | ||
{ | ||
"currentImageId": "01d120000000", | ||
"id": "c79120000000", | ||
"imageName": "mock/updt2:latest", | ||
"latestImageId": "d0a120000000", | ||
"name": "updt2", | ||
"state": "Updated" | ||
} | ||
] | ||
}, | ||
"title": "Watchtower updates on Mock" | ||
}` | ||
data := mockDataFromStates(s.UpdatedState, s.FreshState, s.FailedState, s.SkippedState, s.UpdatedState) | ||
Expect(getTemplatedResult(`json.v1`, false, data)).To(MatchJSON(expected)) | ||
}) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package notifications | ||
|
||
import ( | ||
t "github.com/containrrr/watchtower/pkg/types" | ||
log "github.com/sirupsen/logrus" | ||
) | ||
|
||
// StaticData is the part of the notification template data model set upon initialization | ||
type StaticData struct { | ||
Title string | ||
Host string | ||
} | ||
|
||
// Data is the notification template data model | ||
type Data struct { | ||
StaticData | ||
Entries []*log.Entry | ||
Report t.Report | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters