@@ -5,13 +5,13 @@ import (
55 "strings"
66 "time"
77
8- cloudflare "github.com/cloudflare/cloudflare-go"
8+ "github.com/cloudflare/cloudflare-go"
99 "github.com/machinebox/graphql"
1010 log "github.com/sirupsen/logrus"
1111 "github.com/spf13/viper"
1212)
1313
14- var (
14+ const (
1515 cfGraphQLEndpoint = "https://api.cloudflare.com/client/v4/graphql/"
1616)
1717
@@ -45,6 +45,35 @@ type cloudflareResponseLogpushAccount struct {
4545 } `json:"viewer"`
4646}
4747
48+ type r2AccountResp struct {
49+ R2StorageGroups []struct {
50+ Dimensions struct {
51+ BucketName string `json:"bucketName"`
52+ } `json:"dimensions"`
53+ Max struct {
54+ MetadataSize uint64 `json:"metadataSize"`
55+ PayloadSize uint64 `json:"payloadSize"`
56+ ObjectCount uint64 `json:"objectCount"`
57+ } `json:"max"`
58+ } `json:"r2StorageAdaptiveGroups"`
59+
60+ R2StorageOperations []struct {
61+ Dimensions struct {
62+ Action string `json:"actionType"`
63+ BucketName string `json:"bucketName"`
64+ } `json:"dimensions"`
65+ Sum struct {
66+ Requests uint64 `json:"requests"`
67+ } `json:"sum"`
68+ } `json:"r2OperationsAdaptiveGroups"`
69+ }
70+
71+ type cloudflareResponseR2Account struct {
72+ Viewer struct {
73+ Accounts []r2AccountResp `json:"accounts"`
74+ }
75+ }
76+
4877type cloudflareResponseLogpushZone struct {
4978 Viewer struct {
5079 Zones []logpushResponse `json:"zones"`
@@ -251,60 +280,38 @@ type lbResp struct {
251280}
252281
253282func fetchZones () []cloudflare.Zone {
254- var api * cloudflare.API
255- var err error
256- if len (viper .GetString ("cf_api_token" )) > 0 {
257- api , err = cloudflare .NewWithAPIToken (viper .GetString ("cf_api_token" ))
258- } else {
259- api , err = cloudflare .New (viper .GetString ("cf_api_key" ), viper .GetString ("cf_api_email" ))
260- }
261- if err != nil {
262- log .Fatal ("failed to make client to fetch zones: " , err )
263- }
264-
265283 ctx := context .Background ()
266- z , err := api .ListZones (ctx )
284+ z , err := cloudflareAPI .ListZones (ctx )
267285 if err != nil {
268- log .Fatal ( "failed to fetch zones: " , err )
286+ log .Fatalf ( "Error fetching zones: %s " , err )
269287 }
270288
271289 return z
272290}
273291
274292func fetchFirewallRules (zoneID string ) map [string ]string {
275- var api * cloudflare.API
276- var err error
277- if len (viper .GetString ("cf_api_token" )) > 0 {
278- api , err = cloudflare .NewWithAPIToken (viper .GetString ("cf_api_token" ))
279- } else {
280- api , err = cloudflare .New (viper .GetString ("cf_api_key" ), viper .GetString ("cf_api_email" ))
281- }
282- if err != nil {
283- log .Fatal ("failed to make client to fetch firewall rules: " , err )
284- }
285-
286293 ctx := context .Background ()
287- listOfRules , _ , err := api .FirewallRules (ctx ,
294+ listOfRules , _ , err := cloudflareAPI .FirewallRules (ctx ,
288295 cloudflare .ZoneIdentifier (zoneID ),
289296 cloudflare.FirewallRuleListParams {})
290297 if err != nil {
291- log .Fatal ( "failed to fetch firewall rules: " , err )
298+ log .Fatalf ( "Error fetching firewall rules: %s " , err )
292299 }
293300 firewallRulesMap := make (map [string ]string )
294301
295302 for _ , rule := range listOfRules {
296303 firewallRulesMap [rule .ID ] = rule .Description
297304 }
298305
299- listOfRulesets , err := api .ListRulesets (ctx , cloudflare .ZoneIdentifier (zoneID ), cloudflare.ListRulesetsParams {})
306+ listOfRulesets , err := cloudflareAPI .ListRulesets (ctx , cloudflare .ZoneIdentifier (zoneID ), cloudflare.ListRulesetsParams {})
300307 if err != nil {
301- log .Fatal ( "failed to fetch list of rulesets for firewall rules: " , err )
308+ log .Fatalf ( "Error listing rulesets: %s " , err )
302309 }
303310 for _ , rulesetDesc := range listOfRulesets {
304311 if rulesetDesc .Phase == "http_request_firewall_managed" {
305- ruleset , err := api .GetRuleset (ctx , cloudflare .ZoneIdentifier (zoneID ), rulesetDesc .ID )
312+ ruleset , err := cloudflareAPI .GetRuleset (ctx , cloudflare .ZoneIdentifier (zoneID ), rulesetDesc .ID )
306313 if err != nil {
307- log .Fatal ( "failed to fetch ruleset for firewall rules: " , err )
314+ log .Fatalf ( "Error fetching ruleset for firewall rules: %s " , err )
308315 }
309316 for _ , rule := range ruleset .Rules {
310317 firewallRulesMap [rule .ID ] = rule .Description
@@ -314,7 +321,7 @@ func fetchFirewallRules(zoneID string) map[string]string {
314321 if rulesetDesc .Phase == "http_request_firewall_custom" {
315322 ruleset , err := api .GetRuleset (ctx , cloudflare .ZoneIdentifier (zoneID ), rulesetDesc .ID )
316323 if err != nil {
317- log .Fatal (err )
324+ log.Fatal ("Error fetching custom firewall rulesets: %s" err )
318325 }
319326 for _ , rule := range ruleset .Rules {
320327 firewallRulesMap [rule .ID ] = rule .Description
@@ -326,21 +333,10 @@ func fetchFirewallRules(zoneID string) map[string]string {
326333}
327334
328335func fetchAccounts () []cloudflare.Account {
329- var api * cloudflare.API
330- var err error
331- if len (viper .GetString ("cf_api_token" )) > 0 {
332- api , err = cloudflare .NewWithAPIToken (viper .GetString ("cf_api_token" ))
333- } else {
334- api , err = cloudflare .New (viper .GetString ("cf_api_key" ), viper .GetString ("cf_api_email" ))
335- }
336- if err != nil {
337- log .Fatal ("failed to make client to fetch accounts: " , err )
338- }
339-
340336 ctx := context .Background ()
341- a , _ , err := api .Accounts (ctx , cloudflare.AccountsListParams {PaginationOptions : cloudflare.PaginationOptions {PerPage : 100 }})
337+ a , _ , err := cloudflareAPI .Accounts (ctx , cloudflare.AccountsListParams {PaginationOptions : cloudflare.PaginationOptions {PerPage : 100 }})
342338 if err != nil {
343- log .Fatal ( "failed to fetch accounts: " , err )
339+ log .Fatalf ( "Error fetching accounts: %s " , err )
344340 }
345341
346342 return a
@@ -580,7 +576,7 @@ func fetchWorkerTotals(accountID string) (*cloudflareResponseAccts, error) {
580576 graphqlClient := graphql .NewClient (cfGraphQLEndpoint )
581577 var resp cloudflareResponseAccts
582578 if err := graphqlClient .Run (ctx , request , & resp ); err != nil {
583- log .Error ( "failed to fetch worker totals: " , err )
579+ log .Errorf ( "Error fetching worker totals: %s " , err )
584580 return nil , err
585581 }
586582
@@ -657,7 +653,7 @@ func fetchLoadBalancerTotals(zoneIDs []string) (*cloudflareResponseLb, error) {
657653 graphqlClient := graphql .NewClient (cfGraphQLEndpoint )
658654 var resp cloudflareResponseLb
659655 if err := graphqlClient .Run (ctx , request , & resp ); err != nil {
660- log .Error ( "failed to fetch load balancer totals: " , err )
656+ log .Errorf ( "Error fetching load balancer totals: %s " , err )
661657 return nil , err
662658 }
663659 return & resp , nil
@@ -709,7 +705,7 @@ func fetchLogpushAccount(accountID string) (*cloudflareResponseLogpushAccount, e
709705 graphqlClient := graphql .NewClient (cfGraphQLEndpoint )
710706 var resp cloudflareResponseLogpushAccount
711707 if err := graphqlClient .Run (ctx , request , & resp ); err != nil {
712- log .Error ( "failed to logpush account info: " , err )
708+ log .Errorf ( "Error fetching logpush account totals: %s " , err )
713709 return nil , err
714710 }
715711 return & resp , nil
@@ -761,13 +757,71 @@ func fetchLogpushZone(zoneIDs []string) (*cloudflareResponseLogpushZone, error)
761757 graphqlClient := graphql .NewClient (cfGraphQLEndpoint )
762758 var resp cloudflareResponseLogpushZone
763759 if err := graphqlClient .Run (ctx , request , & resp ); err != nil {
764- log .Error ( "failed to fetch logpush zone: " , err )
760+ log .Errorf ( "Error fetching logpush zone totals: %s " , err )
765761 return nil , err
766762 }
767763
768764 return & resp , nil
769765}
770766
767+ func fetchR2Account (accountID string ) (* cloudflareResponseR2Account , error ) {
768+ now := time .Now ().Add (- time .Duration (viper .GetInt ("scrape_delay" )) * time .Second ).UTC ()
769+ s := 60 * time .Second
770+ now = now .Truncate (s )
771+
772+ request := graphql .NewRequest (`query($accountID: String!, $limit: Int!, $date: String!) {
773+ viewer {
774+ accounts(filter: {accountTag : $accountID }) {
775+ r2StorageAdaptiveGroups(
776+ filter: {
777+ date: $date
778+ },
779+ limit: $limit
780+ ) {
781+ dimensions {
782+ bucketName
783+ }
784+ max {
785+ metadataSize
786+ payloadSize
787+ objectCount
788+ }
789+ }
790+ r2OperationsAdaptiveGroups(filter: { date: $date }, limit: $limit) {
791+ dimensions {
792+ actionType
793+ bucketName
794+ }
795+ sum {
796+ requests
797+ }
798+ }
799+ }
800+ }
801+ }` )
802+
803+ if len (viper .GetString ("cf_api_token" )) > 0 {
804+ request .Header .Set ("Authorization" , "Bearer " + viper .GetString ("cf_api_token" ))
805+ } else {
806+ request .Header .Set ("X-AUTH-EMAIL" , viper .GetString ("cf_api_email" ))
807+ request .Header .Set ("X-AUTH-KEY" , viper .GetString ("cf_api_key" ))
808+ }
809+
810+ request .Var ("accountID" , accountID )
811+ request .Var ("limit" , 9999 )
812+ request .Var ("date" , now .Format ("2006-01-02" ))
813+
814+ ctx := context .Background ()
815+ graphqlClient := graphql .NewClient (cfGraphQLEndpoint )
816+ graphqlClient .Log = func (s string ) { log .Debug (s ) }
817+ var resp cloudflareResponseR2Account
818+ if err := graphqlClient .Run (ctx , request , & resp ); err != nil {
819+ log .Errorf ("Error fetching R2 account: %s" , err )
820+ return nil , err
821+ }
822+ return & resp , nil
823+ }
824+
771825func findZoneAccountName (zones []cloudflare.Zone , ID string ) (string , string ) {
772826 for _ , z := range zones {
773827 if z .ID == ID {
0 commit comments