github.com/letsencrypt/boulder@v0.20251208.0/cmd/admin/overrides_dump.go (about) 1 package main 2 3 import ( 4 "context" 5 "errors" 6 "flag" 7 "fmt" 8 "io" 9 10 "github.com/letsencrypt/boulder/config" 11 "github.com/letsencrypt/boulder/ratelimits" 12 "google.golang.org/protobuf/types/known/emptypb" 13 ) 14 15 type subcommandDumpEnabledOverrides struct { 16 file string 17 } 18 19 func (*subcommandDumpEnabledOverrides) Desc() string { 20 return "Dump all enabled rate limit overrides to a CSV file" 21 } 22 23 func (c *subcommandDumpEnabledOverrides) Flags(f *flag.FlagSet) { 24 f.StringVar(&c.file, "file", "", "destination path for YAML output (required)") 25 } 26 27 func (c *subcommandDumpEnabledOverrides) Run(ctx context.Context, a *admin) error { 28 if c.file == "" { 29 return errors.New("--file is required") 30 } 31 32 stream, err := a.sac.GetEnabledRateLimitOverrides(ctx, &emptypb.Empty{}) 33 if err != nil { 34 return fmt.Errorf("fetching enabled overrides: %w", err) 35 } 36 37 overrides := make(ratelimits.Limits) 38 for { 39 r, err := stream.Recv() 40 if err != nil { 41 if err == io.EOF { 42 break 43 } 44 return fmt.Errorf("reading overrides stream: %w", err) 45 } 46 47 overrides[r.Override.BucketKey] = &ratelimits.Limit{ 48 Burst: r.Override.Burst, 49 Count: r.Override.Count, 50 Period: config.Duration{Duration: r.Override.Period.AsDuration()}, 51 Name: ratelimits.Name(r.Override.LimitEnum), 52 Comment: fmt.Sprintf("Last Updated: %s - %s", 53 r.UpdatedAt.AsTime().Format("2006-01-02"), 54 r.Override.Comment, 55 ), 56 } 57 } 58 59 err = ratelimits.DumpOverrides(c.file, overrides) 60 if err != nil { 61 return fmt.Errorf("dumping overrides: %w", err) 62 } 63 64 a.log.Infof("Wrote %d overrides to %q\n", len(overrides), c.file) 65 return nil 66 }