doggo/internal/app/output.go

151 lines
3.8 KiB
Go
Raw Normal View History

package app
2020-12-12 11:57:13 +01:00
2020-12-12 15:10:28 +01:00
import (
2020-12-13 05:04:53 +01:00
"encoding/json"
2020-12-12 15:10:28 +01:00
"fmt"
2020-12-13 04:17:07 +01:00
"os"
2020-12-12 15:10:28 +01:00
"github.com/fatih/color"
"github.com/miekg/dns"
"github.com/mr-karan/doggo/pkg/resolvers"
2020-12-13 04:17:07 +01:00
"github.com/olekukonko/tablewriter"
2020-12-12 15:10:28 +01:00
)
func (app *App) outputJSON(rsp []resolvers.Response) {
2020-12-24 17:25:20 +01:00
// Pretty print with 4 spaces.
res, err := json.MarshalIndent(rsp, "", " ")
2020-12-13 05:04:53 +01:00
if err != nil {
app.Logger.WithError(err).Error("unable to output data in JSON")
app.Logger.Exit(-1)
2020-12-13 05:04:53 +01:00
}
fmt.Printf("%s", res)
}
func (app *App) outputShort(rsp []resolvers.Response) {
for _, r := range rsp {
for _, a := range r.Answers {
fmt.Printf("%s\n", a.Address)
}
}
}
func (app *App) outputTerminal(rsp []resolvers.Response) {
2020-12-24 17:25:20 +01:00
var (
green = color.New(color.FgGreen, color.Bold).SprintFunc()
blue = color.New(color.FgBlue, color.Bold).SprintFunc()
yellow = color.New(color.FgYellow, color.Bold).SprintFunc()
cyan = color.New(color.FgCyan, color.Bold).SprintFunc()
red = color.New(color.FgRed, color.Bold).SprintFunc()
magenta = color.New(color.FgMagenta, color.Bold).SprintFunc()
)
// Disables colorized output if user specified.
if !app.QueryFlags.Color {
2020-12-24 17:25:20 +01:00
color.NoColor = true
2020-12-13 16:33:44 +01:00
}
2020-12-13 04:17:07 +01:00
2020-12-24 17:25:20 +01:00
// Conditional Time column.
2020-12-13 04:17:07 +01:00
table := tablewriter.NewWriter(os.Stdout)
2020-12-13 09:42:24 +01:00
header := []string{"Name", "Type", "Class", "TTL", "Address", "Nameserver"}
if app.QueryFlags.DisplayTimeTaken {
2020-12-13 04:17:07 +01:00
header = append(header, "Time Taken")
}
2020-12-24 17:25:20 +01:00
// Show output in case if it's not
// a NOERROR.
outputStatus := false
2020-12-24 17:25:20 +01:00
for _, r := range rsp {
for _, a := range r.Authorities {
if dns.StringToRcode[a.Status] != dns.RcodeSuccess {
outputStatus = true
}
}
for _, a := range r.Answers {
if dns.StringToRcode[a.Status] != dns.RcodeSuccess {
outputStatus = true
}
}
}
2020-12-24 17:25:20 +01:00
if outputStatus {
header = append(header, "Status")
}
2020-12-24 17:25:20 +01:00
// Formatting options for the table.
2020-12-13 09:42:24 +01:00
table.SetHeader(header)
table.SetAutoWrapText(true)
2020-12-13 09:26:38 +01:00
table.SetAutoFormatHeaders(true)
2020-12-13 09:42:24 +01:00
table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
table.SetAlignment(tablewriter.ALIGN_LEFT)
table.SetCenterSeparator("")
table.SetColumnSeparator("")
table.SetRowSeparator("")
table.SetHeaderLine(false)
table.SetBorder(false)
table.SetTablePadding("\t") // pad with tabs
table.SetNoWhiteSpace(true)
2020-12-13 04:17:07 +01:00
2020-12-24 17:25:20 +01:00
for _, r := range rsp {
for _, ans := range r.Answers {
var typOut string
switch typ := ans.Type; typ {
case "A":
typOut = blue(ans.Type)
case "AAAA":
typOut = blue(ans.Type)
case "MX":
typOut = magenta(ans.Type)
case "NS":
typOut = cyan(ans.Type)
case "CNAME":
typOut = yellow(ans.Type)
case "TXT":
typOut = yellow(ans.Type)
case "SOA":
typOut = red(ans.Type)
default:
typOut = blue(ans.Type)
}
output := []string{green(ans.Name), typOut, ans.Class, ans.TTL, ans.Address, ans.Nameserver}
// Print how long it took
if app.QueryFlags.DisplayTimeTaken {
2020-12-24 17:25:20 +01:00
output = append(output, ans.RTT)
}
if outputStatus {
output = append(output, red(ans.Status))
}
table.Append(output)
2020-12-13 05:04:53 +01:00
}
2020-12-24 17:25:20 +01:00
for _, auth := range r.Authorities {
var typOut string
switch typ := auth.Type; typ {
case "SOA":
typOut = red(auth.Type)
default:
typOut = blue(auth.Type)
}
output := []string{green(auth.Name), typOut, auth.Class, auth.TTL, auth.MName, auth.Nameserver}
// Print how long it took
if app.QueryFlags.DisplayTimeTaken {
2020-12-24 17:25:20 +01:00
output = append(output, auth.RTT)
}
if outputStatus {
output = append(output, red(auth.Status))
}
table.Append(output)
}
2020-12-13 05:04:53 +01:00
}
table.Render()
}
// Output takes a list of `dns.Answers` and based
// on the output format specified displays the information.
func (app *App) Output(responses []resolvers.Response) {
if app.QueryFlags.ShowJSON {
app.outputJSON(responses)
} else if app.QueryFlags.ShortOutput {
app.outputShort(responses)
2020-12-13 05:04:53 +01:00
} else {
app.outputTerminal(responses)
2020-12-13 05:04:53 +01:00
}
}