Skip to content

Commit

Permalink
adding auto purge of alerts database based on num days and linked inc…
Browse files Browse the repository at this point in the history
…idents
  • Loading branch information
shortstack committed Jan 21, 2025
1 parent 9b28079 commit 9735362
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 4 deletions.
4 changes: 3 additions & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
NIMS_ASSETS_DATABASE_ID=
NIMS_ALERTS_DATABASE_ID=
NOTION_AUTH_TOKEN=
NOTION_AUTH_TOKEN=
NOTION_ALERT_AGE=30
AUTO_PURGE_ALERTS=false
4 changes: 2 additions & 2 deletions NOTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ You need both the `Asset Database` ID and the `Alert Database` ID to use this to
* Link: `https://www.notion.so/184cdc5a1ef3710badc2d2b1271aeb81?v=174cdc3a1ef181719981000cab12bf54&pvs=4`
* ID: `184cdc5a1ef3710badc2d2b1271aeb81`
4. Copy the ID
5. Repeat the above for the other database
5. Repeat the above for the `Alert Database`

## Auth Token and Access

Expand Down Expand Up @@ -50,4 +50,4 @@ This will walk you through creating a Notion integration, getting the auth token
8. Click `Confirm`
![connection](./screenshots/confirm.png)

9. Repeat steps 7 and 8 for the `Asset Database`
9. Repeat steps 7 and 8 for the `Incident Database` and `Asset Database`
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,14 @@ Either build the binary (steps above) if you wish to make modifications, or down
First, replace Notion auth token and database IDs with yours in `.env`.

You can generate and configure your auth token by following the steps in [NOTION.md](./NOTION.md).

This binary will purge alerts not associated with an incident and older than `NOTION_ALERT_AGE` (in days) automatically if `AUTO_PURGE_ALERTS` is set to `true`.
```bash
NIMS_ASSETS_DATABASE_ID=
NIMS_ALERTS_DATABASE_ID=
NOTION_AUTH_TOKEN=
NOTION_ALERT_AGE=30
AUTO_PURGE_ALERTS=false
```
Run the binary
```bash
Expand Down
83 changes: 82 additions & 1 deletion nims-webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ var (
assetsDatabaseID string
alertsDatabaseID string
authToken string
alertAge int
autoPurge bool
)

func init() {
Expand All @@ -32,11 +34,79 @@ func init() {
assetsDatabaseID = os.Getenv("NIMS_ASSETS_DATABASE_ID")
alertsDatabaseID = os.Getenv("NIMS_ALERTS_DATABASE_ID")
authToken = os.Getenv("NOTION_AUTH_TOKEN")
autoPurgeStr := os.Getenv("AUTO_PURGE_ALERTS")
autoPurge, err = strconv.ParseBool(autoPurgeStr)
if err != nil {
log.Fatalf("Invalid boolean value for AUTO_PURGE_ALERTS: %v\n", err)
autoPurge = false
}
alertAge, err = strconv.Atoi(os.Getenv("NOTION_ALERT_AGE"))
if err != nil {
log.Fatalf("invalid value for NOTION_ALERT_AGE: %v\n", err)
}

// initialize notion client
client = notionapi.NewClient(notionapi.Token(authToken))
}

func deleteRecord(recordID string) error {
pageID := notionapi.PageID(recordID)

// set archived to true
_, err := client.Page.Update(context.Background(), pageID, &notionapi.PageUpdateRequest{
Archived: true,
})
if err != nil {
return fmt.Errorf("unable to delete record: %v", err)
}

return nil
}

func deleteOldAlerts(databaseID string, days int) error {

// define the filter for "Created Time" older than $days and "Related Incident" is empty
daysAgo := time.Now().AddDate(0, 0, -days)
timeObj, _ := time.Parse(time.RFC3339, daysAgo.Format(time.RFC3339))
dateObj := notionapi.Date(timeObj)

filter := &notionapi.DatabaseQueryRequest{
Filter: notionapi.AndCompoundFilter{
notionapi.TimestampFilter{
Timestamp: notionapi.TimestampCreated,
CreatedTime: &notionapi.DateFilterCondition{
Before: &dateObj,
},
},
notionapi.PropertyFilter{
Property: "Related Incident",
Relation: &notionapi.RelationFilterCondition{
IsEmpty: true,
},
},
},
}

// Query the database
response, err := client.Database.Query(context.Background(), notionapi.DatabaseID(databaseID), filter)
if err != nil {
return fmt.Errorf("failed to query the database: %v", err)
}

// Iterate through the results and delete matching alerts
for _, result := range response.Results {
fmt.Printf("%s - deleting alert with ID %s - %s\n", time.Now().UTC().Format(time.RFC3339), result.ID, result.Properties["Name"].(*notionapi.TitleProperty).Title[0].Text.Content)

if err := deleteRecord(string(result.ID)); err != nil {
fmt.Printf("%s - failed to delete alert with ID %s: %v\n", time.Now().UTC().Format(time.RFC3339), result.ID, err)
} else {
fmt.Printf("%s - successfully deleted alert with ID %s\n", time.Now().UTC().Format(time.RFC3339), result.ID)
}
}

return nil
}

func checkRelatedAssetExists(name string) (notionapi.ObjectID, error) {
// search for the asset by title (name)
filter := notionapi.PropertyFilter{
Expand Down Expand Up @@ -281,8 +351,19 @@ func webhookHandler(w http.ResponseWriter, r *http.Request) {
}

func main() {

if autoPurge {
// start a goroutine for the 24-hour cron job to purge unassociated alerts
go func() {
for {
deleteOldAlerts(alertsDatabaseID, alertAge)
time.Sleep(24 * time.Hour)
}
}()
}

// listen on port 9000 for webhook POST requests
http.HandleFunc("/hooks/alert", webhookHandler)
log.Println("Listening for webhooks on port 9000")
fmt.Printf("%s - listening for webhooks on port 9000\n", time.Now().UTC().Format(time.RFC3339))
log.Fatal(http.ListenAndServe(":9000", nil))
}

0 comments on commit 9735362

Please sign in to comment.