Initial commit
This commit is contained in:
commit
fb4926df1e
30
cmd/main.go
Normal file
30
cmd/main.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"git.linuxrocker.com/mattburchett/go_tab-magic/pkg/config"
|
||||||
|
"git.linuxrocker.com/mattburchett/go_tab-magic/pkg/resolver"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var c string
|
||||||
|
var debug bool
|
||||||
|
|
||||||
|
flag.StringVar(&c, "config", "", "Configuration to load")
|
||||||
|
flag.BoolVar(&debug, "debug", false, "Enables Debugging Mode")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
// Stop the app if they're missing required flags.
|
||||||
|
if c == "" {
|
||||||
|
log.Fatal("You need to specify a configuration file.")
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg, err := config.GetConfig(c, debug)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resolver.PerformZoneTransfer(cfg)
|
||||||
|
}
|
5
config.json
Normal file
5
config.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"resolver": "172.19.0.5",
|
||||||
|
"resolverPort": 53,
|
||||||
|
"domains": [ "kc.linuxrocker.com"]
|
||||||
|
}
|
43
pkg/config/config.go
Normal file
43
pkg/config/config.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config - This struct will hold configuration components.
|
||||||
|
type Config struct {
|
||||||
|
Resolver string `json:"resolver"`
|
||||||
|
ResolverPort int `json:"resolverPort"`
|
||||||
|
Domains []string `json:"domains"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//GetConfig gets the configuration values for the api using the file in the supplied configPath.
|
||||||
|
func GetConfig(configPath string, debug bool) (Config, error) {
|
||||||
|
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
||||||
|
return Config{}, fmt.Errorf("could not find the config file at path %s", configPath)
|
||||||
|
}
|
||||||
|
if debug {
|
||||||
|
log.Println("Loading Configuration File: " + configPath)
|
||||||
|
}
|
||||||
|
return loadConfigFromFile(configPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
//if the config loaded from the file errors, no defaults will be loaded and the app will exit.
|
||||||
|
func loadConfigFromFile(configPath string) (conf Config, err error) {
|
||||||
|
file, err := os.Open(configPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error opening config file: %v", err)
|
||||||
|
} else {
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(file).Decode(&conf)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error decoding config file: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return conf, err
|
||||||
|
}
|
13
pkg/model/model.go
Normal file
13
pkg/model/model.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type Results struct {
|
||||||
|
IP string `json:"ip"`
|
||||||
|
Hostname string `json:"hostname"`
|
||||||
|
TXT string `json:"TXT,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UniqResults struct {
|
||||||
|
IP string `json:"ip"`
|
||||||
|
Hostname string `json:"hostname"`
|
||||||
|
TXT string `json:"TXT,omitempty"`
|
||||||
|
}
|
74
pkg/resolver/resolver.go
Normal file
74
pkg/resolver/resolver.go
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package resolver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.linuxrocker.com/mattburchett/go_tab-magic/pkg/config"
|
||||||
|
"github.com/miekg/dns"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LookupName returns IPv4 address from A record or error.
|
||||||
|
func lookupName(fqdn, serverAddr string) (string, error) {
|
||||||
|
m := &dns.Msg{}
|
||||||
|
m.SetQuestion(dns.Fqdn(fqdn), dns.TypeA)
|
||||||
|
in, err := dns.Exchange(m, serverAddr)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if len(in.Answer) < 1 {
|
||||||
|
return "", errors.New("no Answer")
|
||||||
|
}
|
||||||
|
if a, ok := in.Answer[0].(*dns.A); ok {
|
||||||
|
ip := a.A.String()
|
||||||
|
return ip, nil
|
||||||
|
}
|
||||||
|
return "", errors.New("no A record returned")
|
||||||
|
}
|
||||||
|
|
||||||
|
func PerformZoneTransfer(config config.Config) {
|
||||||
|
data := make([]string, 0)
|
||||||
|
|
||||||
|
// Do the transfer
|
||||||
|
for _, i := range config.Domains {
|
||||||
|
server := fmt.Sprintf("%s:%d", config.Resolver, config.ResolverPort)
|
||||||
|
tr := dns.Transfer{}
|
||||||
|
m := &dns.Msg{}
|
||||||
|
m.SetAxfr(dns.Fqdn(i))
|
||||||
|
in, err := tr.In(m, server)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
for ex := range in {
|
||||||
|
for _, a := range ex.RR {
|
||||||
|
var ip, hostname, txt string
|
||||||
|
switch v := a.(type) {
|
||||||
|
case *dns.TXT:
|
||||||
|
txt = string(v.Txt[0])
|
||||||
|
hostname = v.Hdr.Name
|
||||||
|
cip, err := lookupName(strings.TrimRight(v.Hdr.Name, "."), server)
|
||||||
|
if err != nil || cip == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ip = cip
|
||||||
|
case *dns.A:
|
||||||
|
ip = v.A.String()
|
||||||
|
hostname = v.Hdr.Name
|
||||||
|
case *dns.CNAME:
|
||||||
|
cip, err := lookupName(v.Target, server)
|
||||||
|
if err != nil || cip == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ip = cip
|
||||||
|
hostname = v.Hdr.Name
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
data = append(data, fmt.Sprintf("%v %v %v", hostname, ip, txt))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println(data)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user