-
Notifications
You must be signed in to change notification settings - Fork 3
/
cf_audit_event_fetcher.go
84 lines (67 loc) · 2.36 KB
/
cf_audit_event_fetcher.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package fetchers
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"code.cloudfoundry.org/lager"
cfclient "github.com/cloudfoundry-community/go-cfclient"
)
type CFAuditEventFetcher = func(pullEventsSince time.Time, resultsChan chan CFAuditEventResult)
func FetchCFAuditEvents(cfg *FetcherConfig, pullEventsSince time.Time, resultsChan chan CFAuditEventResult) {
fetchEvents(cfg, startPageURL(pullEventsSince), resultsChan)
}
type CFAuditEventResult struct {
Events []cfclient.Event
Err error
}
func startPageURL(pullEventsSince time.Time) string {
timestamp := fmt.Sprintf("timestamp>%s", pullEventsSince.Format("2006-01-02T15:04:05Z"))
q := url.Values{}
q.Set("q", timestamp)
q.Set("results-per-page", "100")
return fmt.Sprintf("/v2/events?%s", q.Encode())
}
func fetchEvents(cfg *FetcherConfig, startPageURL string, resultsChan chan CFAuditEventResult) {
defer close(resultsChan)
logger := cfg.Logger.WithData(lager.Data{"start_page_url": startPageURL})
logger.Info("fetching")
nextPageURL := startPageURL
var events []cfclient.Event
var err error
for nextPageURL != "" {
logger = logger.WithData(lager.Data{"page_url": nextPageURL})
nextPageURL, events, err = getPage(cfg.CFClient, nextPageURL)
if err != nil {
logger.Error("fetched.page.error", err)
resultsChan <- CFAuditEventResult{Err: err}
return
}
logger.Info("fetched.page.ok", lager.Data{"event_count": len(events)})
resultsChan <- CFAuditEventResult{Events: events}
time.Sleep(cfg.PaginationWaitTime)
}
}
func getPage(cfClient cfclient.CloudFoundryClient, url string) (string, []cfclient.Event, error) {
resp, err := cfClient.DoRequest(cfClient.NewRequest("GET", url))
if err != nil {
return "", nil, fmt.Errorf("error requesting events: %s", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
// This only occurs when the status code is < 400
return "", nil, fmt.Errorf("request failed with status code %d", resp.StatusCode)
}
var eventResp cfclient.EventsResponse
if err := json.NewDecoder(resp.Body).Decode(&eventResp); err != nil {
return "", nil, fmt.Errorf("error unmarshaling events: %s", err)
}
events := make([]cfclient.Event, len(eventResp.Resources))
for i, e := range eventResp.Resources {
e.Entity.GUID = e.Meta.Guid
e.Entity.CreatedAt = e.Meta.CreatedAt
events[i] = e.Entity
}
return eventResp.NextURL, events, nil
}