Skip to content

Commit

Permalink
Better dns errors (#36)
Browse files Browse the repository at this point in the history
* Clean up logging

* Return the errors and not the error string

* Bump error reporting to info level
  • Loading branch information
Cyb3r-Jak3 authored Aug 20, 2023
1 parent ccf3d85 commit c51f1eb
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 44 deletions.
37 changes: 22 additions & 15 deletions cmd/cloudflare-utils/dns-cleaner.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/Cyb3r-Jak3/common/v5"
"github.com/cloudflare/cloudflare-go"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
"gopkg.in/yaml.v3"
)
Expand Down Expand Up @@ -100,17 +101,17 @@ func buildDNSCleanerCommand() *cli.Command {
// DNSCleaner is the main action function for the dns-cleaner command.
// It checks if a DNS file exists. If there isn't a DNS file then it downloads records, if there is a file there then it uploads records.
func DNSCleaner(c *cli.Context) error {
logger.Info("Starting DNS Cleaner")
logger.Infoln("Starting DNS Cleaner")

fileExists := common.FileExists(c.String(dnsFileFlag))
logger.Debugf("Existing DNS file: %t", fileExists)
logger.Debugf("Existing DNS file: %t\n", fileExists)
if !fileExists {
logger.Info("Downloading DNS Records")
logger.Infoln("Downloading DNS Records")
if err := DownloadDNS(c); err != nil {
return err
}
} else {
logger.Info("Uploading DNS Records")
logger.Infoln("Uploading DNS Records")
if err := UploadDNS(c); err != nil {
return err
}
Expand All @@ -121,9 +122,9 @@ func DNSCleaner(c *cli.Context) error {
// quickClean checks to see if a DNS record is numeric.
func quickClean(zoneName, record string) bool {
r := strings.Split(record, fmt.Sprintf(".%s", zoneName))[0]
logger.Debugf("Stripped record: %s", r)
logger.Debugf("Stripped record: %s\n", r)
_, err := strconv.Atoi(r)
logger.Debugf("Error converting: %t", err != nil)
logger.Debugf("Error converting: %t\n", err != nil)
return err != nil
}

Expand All @@ -143,7 +144,7 @@ func DownloadDNS(c *cli.Context) error {
}
records, _, err := APIClient.ListDNSRecords(ctx, cloudflare.ZoneIdentifier(zoneID), cloudflare.ListDNSRecordsParams{})
if err != nil {
logger.WithError(err).Error("Error getting zone info with ID")
logger.WithError(err).Errorln("Error getting zone info with ID")
return err
}
recordFile := &RecordFile{
Expand Down Expand Up @@ -175,11 +176,11 @@ func DownloadDNS(c *cli.Context) error {
}
data, err := yaml.Marshal(&recordFile)
if err != nil {
logger.WithError(err).Error("Error marshalling yaml data")
logger.WithError(err).Errorln("Error marshalling yaml data")
return err
}
if err := os.WriteFile(c.String(dnsFileFlag), data, 0600); err != nil {
logger.WithError(err).Error("Error writing DNS file")
logger.WithError(err).Errorln("Error writing DNS file")
return err
}
return nil
Expand All @@ -194,13 +195,13 @@ func UploadDNS(c *cli.Context) error {

file, err := os.ReadFile(dnsFilePath)
if err != nil {
logger.WithError(err).Error("Error reading DNS file")
logger.WithError(err).Errorln("Error reading DNS file")
return err
}

recordFile := &RecordFile{}
if err := yaml.Unmarshal(file, recordFile); err != nil {
logger.WithError(err).Error("Error unmarshalling yaml")
logger.WithError(err).Errorln("Error unmarshalling yaml")
return err
}

Expand All @@ -224,19 +225,25 @@ func UploadDNS(c *cli.Context) error {
fmt.Printf("Dry Run: Would have removed %d records\n", len(toRemove))
return nil
}

errorCount = len(RapidDNSDelete(c.Context, zoneResource, toRemove))
removeErrors := RapidDNSDelete(c.Context, zoneResource, toRemove)
errorCount = len(removeErrors)

if errorCount == 0 {
fmt.Printf("Successfully deleted all %d dns records\n", len(toRemove))
} else {
fmt.Printf("Error deleting %d dns records.\nPlease review errors and reach out if you believe to be an error with the program", errorCount)
fmt.Printf("Error deleting %d dns records.\nPlease review errors and reach out if you believe to be an error with the program\n", errorCount)
if logger.IsLevelEnabled(logrus.InfoLevel) {
logger.Infoln("Errors:")
for deleteID, deleteErr := range removeErrors {
logger.Debugf("Error deleting record: %s: %s\n", deleteID, deleteErr)
}
}
}

logger.Infof("%d total records. %d to removed. %d errors removing records", recordCount, len(toRemove), errorCount)
if c.Bool(removeDNSFileFlag) {
if err := os.Remove(dnsFilePath); err != nil {
logger.WithError(err).Warn("Error deleting old DNS file")
logger.WithError(err).Warnln("Error deleting old DNS file")
}
}
return nil
Expand Down
2 changes: 1 addition & 1 deletion cmd/cloudflare-utils/dns-purge.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func DNSPurge(c *cli.Context) error {
if errorCount == 0 {
fmt.Printf("Successfully deleted all %d dns records\n", len(records))
} else {
fmt.Printf("Error deleting %d dns records.\nPlease review errors and reach out if you believe to be an error with the program", errorCount)
fmt.Printf("Error deleting %d dns records.\nPlease review errors and reach out if you believe to be an error with the program\n", errorCount)
}
return nil
}
10 changes: 5 additions & 5 deletions cmd/cloudflare-utils/prune-deployments.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,13 @@ func PruneDeploymentsRoot(c *cli.Context) error {
var toDelete []cloudflare.PagesProjectDeployment

if c.String(branchNameFlag) != "" {
logger.Info("Pruning by branch")
logger.Infoln("Pruning by branch")
toDelete = PruneBranchDeployments(options)
} else if c.Timestamp(beforeFlag) != nil || c.Timestamp(afterFlag) != nil {
logger.Info("Pruning by time")
logger.Infoln("Pruning by time")
toDelete = PruneTimeDeployments(options)
} else {
logger.Info("Purging all deployments")
logger.Infoln("Purging all deployments")
toDelete = options.SelectedDeployments
}

Expand Down Expand Up @@ -161,9 +161,9 @@ func PruneTimeDeployments(options pruneDeploymentOptions) (toDelete []cloudflare
beforeTimestamp := options.c.Timestamp(beforeFlag)
afterTimestamp := options.c.Timestamp(afterFlag)
if beforeTimestamp != nil {
logger.Debug("Pruning with before time")
logger.Debugln("Pruning with before time")
} else {
logger.Debug("Pruning with after time")
logger.Debugln("Pruning with after time")
}
for _, deployment := range options.SelectedDeployments {
if beforeTimestamp != nil {
Expand Down
54 changes: 31 additions & 23 deletions cmd/cloudflare-utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"github.com/urfave/cli/v2"
)

const maxGoRoutines = 10

// SetLogLevel sets the log level based on the CLI flags.
func SetLogLevel(c *cli.Context, logger *logrus.Logger) {
if c.Bool("debug") {
Expand All @@ -32,8 +34,8 @@ func SetLogLevel(c *cli.Context, logger *logrus.Logger) {
logger.SetLevel(logrus.WarnLevel)
}
}
logger.Debugf("Log Level set to %v", logger.Level)
logger.Debugf("cloudflare-utils: %s", versionString)
logger.Debugf("Log Level set to %v\n", logger.Level)
logger.Debugf("cloudflare-utils: %s\n", versionString)
}

// GetZoneID gets the zone ID from the CLI flags either by name or ID.
Expand All @@ -47,7 +49,7 @@ func GetZoneID(c *cli.Context) (string, error) {
if zoneID == "" {
id, err := APIClient.ZoneIDByName(zoneName)
if err != nil {
logger.WithError(err).Error("Error getting zone id from name")
logger.WithError(err).Errorln("Error getting zone id from name")
return "", err
}
zoneID = id
Expand Down Expand Up @@ -77,7 +79,7 @@ func DeploymentsPaginate(params PagesDeploymentPaginationOptions) ([]cloudflare.
})
if err != nil {
if len(deployments) != 0 {
logger.WithError(err).Error("Unable to get any deployments")
logger.WithError(err).Errorln("Unable to get any deployments")
return deployments, fmt.Errorf("error listing deployments: %w", err)
}
return []cloudflare.PagesProjectDeployment{}, fmt.Errorf("error listing deployments: %w", err)
Expand All @@ -88,52 +90,58 @@ func DeploymentsPaginate(params PagesDeploymentPaginationOptions) ([]cloudflare.
break
}
}
logger.Debugf("Got %d deployments in %s", len(deployments), time.Since(startDeploymentListing))
logger.Debugf("Got %d deployments in %s\n", len(deployments), time.Since(startDeploymentListing))
return deployments, nil
}

// RapidDNSDelete is a helper function to delete DNS records quickly.
// Uses a pool of goroutines to delete records in parallel.
func RapidDNSDelete(ctx context.Context, rc *cloudflare.ResourceContainer, dnsRecords []cloudflare.DNSRecord) []string {
p := pool.NewWithResults[string]()
p.WithMaxGoroutines(50)
func RapidDNSDelete(ctx context.Context, rc *cloudflare.ResourceContainer, dnsRecords []cloudflare.DNSRecord) map[string]error {
p := pool.NewWithResults[bool]()
results := make(map[string]error)
p.WithMaxGoroutines(maxGoRoutines)
for _, dnsRecord := range dnsRecords {
p.Go(func() string {
p.Go(func() bool {
err := APIClient.DeleteDNSRecord(ctx, rc, dnsRecord.ID)
if err != nil {
logger.WithError(err).Warningf("Error deleting dnsRecord: %s", dnsRecord.ID)
return dnsRecord.ID
logger.WithError(err).Warningf("Error deleting DNS record: %s\n", dnsRecord.ID)
results[dnsRecord.ID] = err
return false
}
return ""
return true
},
)
}
return p.Wait()
p.Wait()
return results
}

// RapidPagesDeploymentDelete is a helper function to delete Pages deployments quickly.
// Uses a pool of goroutines to delete deployments in parallel.
func RapidPagesDeploymentDelete(options pruneDeploymentOptions) []string {
p := pool.NewWithResults[string]()
maxGoRoutines := 50
func RapidPagesDeploymentDelete(options pruneDeploymentOptions) map[string]error {
p := pool.NewWithResults[bool]()
goRoutines := maxGoRoutines
if options.c.Bool(lotsOfDeploymentsFlag) {
maxGoRoutines = 10
goRoutines = 5
}
p.WithMaxGoroutines(maxGoRoutines)
results := make(map[string]error)
p.WithMaxGoroutines(goRoutines)
for _, deployment := range options.SelectedDeployments {
p.Go(func() string {
p.Go(func() bool {
err := APIClient.DeletePagesDeployment(options.c.Context, options.ResourceContainer, cloudflare.DeletePagesDeploymentParams{
ProjectName: options.ProjectName,
DeploymentID: deployment.ID,
Force: true,
})
if err != nil {
logger.WithError(err).Warningf("Error deleting deployment: %s", deployment.ID)
return deployment.ID
logger.WithError(err).Warningf("Error deleting deployment: %s\n", deployment.ID)
results[deployment.ID] = err
return false
}
return ""
return true
},
)
}
return p.Wait()
p.Wait()
return results
}

0 comments on commit c51f1eb

Please sign in to comment.