Skip to content

Commit

Permalink
Version v1.1.0
Browse files Browse the repository at this point in the history
- Add template header and footer support
  • Loading branch information
pabateman authored Jun 15, 2024
2 parents 4779f60 + 6a167c7 commit 067a17c
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 58 deletions.
3 changes: 1 addition & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ gitignore:
.PHONY: lint
lint:
golangci-lint run \
--timeout=3m \
--exclude-dirs hack
--timeout=3m

.INTERMEDIATE: $(DISTFILE:.gz=)
$(DISTFILE:.gz=): $(BUILDDIR)
Expand Down
59 changes: 55 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,19 +317,70 @@ terraform.io,76.76.21.21

### Template

Additionally, you can specify your own template for the lookup result for every task separately. The only available variables are `{{host}}` for the host and `{{address}}` for addresses:
Additionally, you can specify your own template for the lookup result for every task separately. You can also specify a header (i.e., the first line) and a footer (i.e., the last line) for the template. The only available variables are `{{host}}` for the host and `{{address}}` for addresses, and these variables are available only for the body of the template..

```bash
$ dns-lookuper -f testdata/lists/1.lst -r template -t "there is {{host}} with address {{address}}"
$ dns-lookuper -f testdata/lists/1.lst -r template -t "there is {{host}} with address {{address}}" --template-header "hello from the header of the template" --template-footer "hello from the footer of the template"
```

Output:

```text
there is cloudflare.com with address 104.16.132.229
hello from the header of the template
there is cloudflare.com with address 104.16.133.229
there is cloudflare.com with address 2606:4700::6810:85e5
there is cloudflare.com with address 104.16.132.229
there is cloudflare.com with address 2606:4700::6810:84e5
there is cloudflare.com with address 2606:4700::6810:85e5
there is hashicorp.com with address 76.76.21.21
there is terraform.io with address 76.76.21.21
hello from the footer of the template
```

Another example for the config file stored in [testdata/config/template.yaml](/testdata/config/template.yaml):

```yaml
tasks:
- files:
- ../lists/1.lst
- ../lists/2.lst
output: '-'
format: template
mode: ipv4
template:
header: |
welcome to my awesome resolved list header
it can be multiline
text: "here is {{host}} with address {{address}}"
footer: |
welcome to my awesome resolved list footer
it can be multiline as well
byebye!
```

```bash
$ dns-lookuper -c testdata/configs/template.yaml
```

```text
welcome to my awesome resolved list header
it can be multiline
here is cloudflare.com with address 104.16.133.229
here is cloudflare.com with address 104.16.132.229
here is google.com with address 142.250.150.138
here is google.com with address 142.250.150.113
here is google.com with address 142.250.150.102
here is google.com with address 142.250.150.100
here is google.com with address 142.250.150.101
here is google.com with address 142.250.150.139
here is hashicorp.com with address 76.76.21.21
here is linked.in with address 108.174.10.24
here is rpm.releases.hashicorp.com with address 52.222.214.72
here is rpm.releases.hashicorp.com with address 52.222.214.58
here is rpm.releases.hashicorp.com with address 52.222.214.125
here is rpm.releases.hashicorp.com with address 52.222.214.123
here is terraform.io with address 76.76.21.21
welcome to my awesome resolved list footer
it can be multiline as well
byebye!
```
79 changes: 52 additions & 27 deletions internal/lookuper/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@ import (
)

const (
argFile = "file"
argOutput = "output"
argMode = "mode"
argFormat = "format"
argTemplate = "template"
argConfig = "config"
argDaemon = "daemon"
argInterval = "interval"
argTimeout = "timeout"
argFile = "file"
argOutput = "output"
argMode = "mode"
argFormat = "format"
argTemplateText = "template-text"
argTemplateHeader = "template-header"
argTemplateFooter = "template-footer"
argConfig = "config"
argDaemon = "daemon"
argInterval = "interval"
argTimeout = "timeout"
)

const (
Expand Down Expand Up @@ -66,11 +68,17 @@ type daemonSettings struct {
}

type task struct {
Files []string `json:"files"`
Output string `json:"output"`
Mode string `json:"mode"`
Format string `json:"format"`
Template string `json:"template"`
Files []string `json:"files"`
Output string `json:"output"`
Mode string `json:"mode"`
Format string `json:"format"`
Template *template `json:"template"`
}

type template struct {
Text string `json:"text"`
Header string `json:"header"`
Footer string `json:"footer"`
}

var (
Expand Down Expand Up @@ -103,10 +111,20 @@ var (
Value: formatDefault,
},
&cli.StringFlag{
Name: argTemplate,
Usage: fmt.Sprintf("output template; required with --%s=%s", argFormat, formatTemplate),
Name: argTemplateText,
Usage: fmt.Sprintf("output template text; required with --%s=%s", argFormat, formatTemplate),
Aliases: []string{"t"},
EnvVars: []string{"DNS_LOOKUPER_TEMPLATE"},
EnvVars: []string{"DNS_LOOKUPER_TEMPLATE_TEXT"},
},
&cli.StringFlag{
Name: argTemplateHeader,
Usage: "output template header",
EnvVars: []string{"DNS_LOOKUPER_TEMPLATE_HEADER"},
},
&cli.StringFlag{
Name: argTemplateFooter,
Usage: "output template footer",
EnvVars: []string{"DNS_LOOKUPER_TEMPLATE_FOOTER"},
},
&cli.StringFlag{
Name: argConfig,
Expand Down Expand Up @@ -140,7 +158,7 @@ var (
formatEnum = []string{formatJSON, formatYAML, formatCSV, formatHosts, formatList, formatTemplate}
modeEnum = []string{modeAll, modeIpv4, modeIpv6}
argsConfigFile = []string{argConfig}
argCmdLine = []string{argDaemon, argFile, argFormat, argInterval, argMode, argOutput, argTemplate, argTimeout}
argCmdLine = []string{argDaemon, argFile, argFormat, argInterval, argMode, argOutput, argTemplateText, argTemplateFooter, argTemplateHeader, argTimeout}
)

func newConfig(clictx *cli.Context) (*Config, error) {
Expand Down Expand Up @@ -177,11 +195,15 @@ func newConfig(clictx *cli.Context) (*Config, error) {

} else if cmdLineIsSet(clictx) {
singleton := task{
Files: clictx.StringSlice(argFile),
Output: clictx.String(argOutput),
Mode: clictx.String(argMode),
Format: clictx.String(argFormat),
Template: clictx.String(argTemplate),
Files: clictx.StringSlice(argFile),
Output: clictx.String(argOutput),
Mode: clictx.String(argMode),
Format: clictx.String(argFormat),
Template: &template{
Header: clictx.String(argTemplateHeader),
Text: clictx.String(argTemplateText),
Footer: clictx.String(argTemplateFooter),
},
}

result.Tasks = append(result.Tasks, singleton)
Expand Down Expand Up @@ -259,12 +281,15 @@ func validateTask(t *task, s *settings) error {
return fmt.Errorf("unsupported output format %s; valid formats are %s", t.Format, formatEnum)
}

if t.Format == formatTemplate && t.Template == "" {
return fmt.Errorf(`you must specify template string (--%[1]s or "%[1]s" key in file) when output format is "%[2]s"`, argTemplate, formatTemplate)
if t.Format == formatTemplate && t.Template.Text == "" {
return fmt.Errorf(`you must specify template text at least (--%[1]s or template key in file) when output format is "%[2]s"`, argTemplateText, formatTemplate)
}

if t.Format != formatTemplate && t.Template != "" {
return fmt.Errorf(`template string allowed only with output format of type "template"`)
if t.Format != formatTemplate &&
(t.Template.Text != "" ||
t.Template.Header != "" ||
t.Template.Footer != "") {
return fmt.Errorf(`template settings allowed only with output format of type "%s"`, formatTemplate)
}

return nil
Expand Down
3 changes: 2 additions & 1 deletion internal/lookuper/lookuper.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ func performTask(t *task, settings *settings) error {
case formatYAML:
printer.fn = printer.printYAML
case formatCSV:
printer.fn = printer.printCSV
printer.task.Template = templateCSV
printer.fn = printer.printTemplate
default:
return fmt.Errorf(`invalid output format "%s"`, t.Format)
}
Expand Down
45 changes: 21 additions & 24 deletions internal/lookuper/printers.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package lookuper

import (
"encoding/csv"
"encoding/json"
"fmt"
"os"
Expand All @@ -21,20 +20,32 @@ type printer struct {
type printerFunc func() error

var (
CSVHeaders = []string{"name", "address"}
templateHosts = "{{address}} {{host}}"
templateCSV = &template{
Header: "name,address",
Text: "{{host}},{{address}}",
}

templateHosts = &template{
Text: "{{address}} {{host}}",
}
)

func (p *printer) print() error {
return p.fn()
}

func (p *printer) printTemplate() error {
t, err := fasttemplate.NewTemplate(p.task.Template, "{{", "}}")
t, err := fasttemplate.NewTemplate(p.task.Template.Text, "{{", "}}")
if err != nil {
return err
}

if p.task.Template.Header != "" {
if _, err := p.file.WriteString(fmt.Sprintln(p.task.Template.Header)); err != nil {
return err
}
}

for _, response := range p.responseList {
for _, address := range response.Addresses {
s := t.ExecuteString(map[string]interface{}{
Expand All @@ -47,6 +58,12 @@ func (p *printer) printTemplate() error {
}
}
}

if p.task.Template.Footer != "" {
if _, err := p.file.WriteString(fmt.Sprintln(p.task.Template.Footer)); err != nil {
return err
}
}
return nil
}

Expand Down Expand Up @@ -99,23 +116,3 @@ func (p *printer) printYAML() error {

return nil
}

func (p *printer) printCSV() error {
encoder := csv.NewWriter(p.file)
defer encoder.Flush()

err := encoder.Write(CSVHeaders)
if err != nil {
return err
}

for _, response := range p.responseList {
for _, address := range response.Addresses {
err = encoder.Write([]string{response.Name, address.String()})
if err != nil {
return err
}
}
}
return nil
}
16 changes: 16 additions & 0 deletions testdata/configs/template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
tasks:
- files:
- ../lists/1.lst
- ../lists/2.lst
output: '-'
format: template
mode: ipv4
template:
header: |
welcome to my awesome resolved list header
it can be multiline
text: "here is {{host}} with address {{address}}"
footer: |
welcome to my awesome resolved list footer
it can be multiline as well
byebye!

0 comments on commit 067a17c

Please sign in to comment.