Skip to content

Commit b8c58f5

Browse files
committed
srv-plz is born
0 parents  commit b8c58f5

File tree

10 files changed

+433
-0
lines changed

10 files changed

+433
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/srv-plz
2+
.task
3+
dist/

.goreleaser.yml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# .goreleaser.yml file
2+
# Copyright (c) 2022 Neomantra BV
3+
# Documentation at http://goreleaser.com
4+
5+
project_name: srv-plz
6+
7+
before:
8+
hooks:
9+
- go mod tidy
10+
11+
builds:
12+
- main: cmd/srv-plz/main.go
13+
id: srv-plz
14+
binary: srv-plz
15+
env:
16+
- CGO_ENABLED=0
17+
goos:
18+
- linux
19+
- windows
20+
- darwin
21+
22+
archives:
23+
- replacements:
24+
darwin: Darwin
25+
linux: Linux
26+
windows: Windows
27+
386: i386
28+
amd64: x86_64
29+
30+
checksum:
31+
name_template: 'checksums.txt'
32+
33+
snapshot:
34+
name_template: "{{ incpatch .Version }}-next"
35+
36+
changelog:
37+
sort: asc
38+
filters:
39+
exclude:
40+
- '^docs:'
41+
- '^test:'
42+
43+
universal_binaries:
44+
- replace: true
45+
46+
release:
47+
github:
48+
owner: neomantra
49+
name: srv-plz
50+
51+
brews:
52+
- homepage: https://github.com/neomantra/srv-plz
53+
description: "SRV record extractor"
54+
folder: Formula
55+
tap:
56+
owner: neomantra
57+
name: homebrew-tap
58+
branch: main
59+
token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}"
60+
commit_author:
61+
name: goreleaserbot
62+
63+
install: |
64+
bin.install "srv-plz"

.vscode/launch.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "srv-plz",
9+
"type": "go",
10+
"request": "launch",
11+
"mode": "auto",
12+
"program": "${workspaceFolder}/cmd/srv-plz",
13+
"args": ["-r", "test.service.consul"],
14+
"env": {
15+
"SRV_DNS": "10.4.20.69:8600"
16+
}
17+
}
18+
]
19+
}

LICENSE.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Copyright (c) 2022 Neomantra BV
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
The above copyright notice and this permission notice shall be included in
10+
all copies or substantial portions of the Software.
11+
12+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
18+
THE SOFTWARE.

README.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# srv-plz - SRV record extractor
2+
3+
## *Service Please!*
4+
5+
`srv-plz` looks up a [DNS SRV record](https://en.wikipedia.org/wiki/SRV_record) from the specified DNS server
6+
and outputs the result.
7+
8+
9+
```
10+
$ SRV_DNS=127.0.0.1:8500 srv-plz example.service.consul
11+
12+
```
13+
14+
## Usage
15+
16+
```
17+
$ srv-plz --help
18+
usage: srv-plz <options> [service1 [service2 [...]]]
19+
20+
srv-plz resolves DNS SRV records and outputs the result.
21+
22+
The resolver is specified with "--dns <ip:port>" argument or by
23+
setting the SRV_DNS environment variable.
24+
25+
If no resolver is specified, the system resolver is used.
26+
27+
-d, --dns string DNS resolver to use (must be in form IP:port)
28+
-h, --help show help
29+
-l, --limit uint32 only return N records (default 1)
30+
-r, --recurse recurse with the same resolver
31+
```
32+
33+
----
34+
35+
## Installing
36+
37+
Binaries for multiple platforms are [released on GitHub](https://github.com/neomantra/srv-plz/releases) through [GitHub Actions](https://github.com/neomantra/srv-plz/actions).
38+
39+
You can also install for various platforms with [Homebrew](https://brew.sh) from [`neomantra/homebrew-tap`](https://github.com/neomantra/homebrew-tap):
40+
41+
```
42+
brew tap neomantra/homebrew-tap
43+
brew install srv-plz
44+
```
45+
46+
----
47+
48+
## Example Usage
49+
50+
Lookup with system resolver, without or with recursion:
51+
52+
```
53+
$ srv-plz _http._tcp.mxtoolbox.com
54+
mxtoolbox.com.:80
55+
56+
$ srv-plz -r _http._tcp.mxtoolbox.com
57+
13.225.202.38:80
58+
```
59+
60+
Lookup with custom resolver, either via CLI or `SRV_DNS` environment variable:
61+
```
62+
$ srv-plz -d 10.4.20.69:8600 -r webserver.service.consul
63+
10.4.20.69:55420
64+
65+
$ SRV_DNS=10.4.20.69:8600 srv-plz -r webserver.service.consul
66+
10.4.20.69:55420
67+
```
68+
69+
----
70+
71+
## Building
72+
73+
Building is performed with [task](https://taskfile.dev/):
74+
75+
```
76+
$ task
77+
task: [build] go build -o srv-plz cmd/srv-plz/main.go
78+
```
79+
80+
----
81+
82+
## Credits and License
83+
84+
Thanks to [github.com/miekg/dns](https://github.com/miekg/dns) for the heavy lifting.
85+
86+
Copyright (c) 2022 Neomantra BV. Authored by Evan Wies.
87+
88+
Released under the [MIT License](https://en.wikipedia.org/wiki/MIT_License), see [LICENSE.txt](./LICENSE.txt).

Taskfile.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
version: '3'
2+
3+
tasks:
4+
build:
5+
cmds:
6+
- go build -o srv-plz cmd/srv-plz/main.go
7+
sources:
8+
- ./**/*.go
9+
generates:
10+
- srv-plz
11+
silent: false
12+
13+
clean:
14+
cmds:
15+
- rm srv-plz
16+
17+
test:
18+
cmds:
19+
#- go test neomantra/srv-plz/pkg/srv-plz
20+
silent: false
21+
22+
default:
23+
cmds:
24+
- task: test
25+
- task: build
26+
27+
28+

cmd/srv-plz/main.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"net"
6+
"os"
7+
8+
"neomantra/srv-plz/pkg/lookup"
9+
10+
"github.com/spf13/pflag"
11+
)
12+
13+
/////////////////////////////////////////////////////////////////////////////////////
14+
15+
var usageFormatShort string = `usage: %s <options> [service1 [service2 [...]]]`
16+
17+
var usageFormat string = `usage: %s <options> [service1 [service2 [...]]]
18+
19+
srv-plz resolves DNS SRV records and outputs the result.
20+
21+
The resolver is specified with "--dns <ip:port>" argument or by setting
22+
the SRV_DNS environment variable. The CLI argument takes precedent.
23+
24+
If no DNS resolver is specified, the system resolver is used.
25+
26+
`
27+
28+
/////////////////////////////////////////////////////////////////////////////////////
29+
30+
func main() {
31+
var dnsServer string
32+
var recurse bool
33+
var numLimit uint32
34+
var showHelp bool
35+
36+
pflag.StringVarP(&dnsServer, "dns", "d", "", "DNS resolver to use (must be in form IP:port)")
37+
pflag.BoolVarP(&recurse, "recurse", "r", false, "recurse with the same resolver")
38+
pflag.Uint32VarP(&numLimit, "limit", "l", 1, "only return N records")
39+
pflag.BoolVarP(&showHelp, "help", "h", false, "show help")
40+
pflag.Parse()
41+
42+
if showHelp {
43+
fmt.Fprintf(os.Stdout, usageFormat, os.Args[0])
44+
pflag.PrintDefaults()
45+
os.Exit(0)
46+
}
47+
48+
// setup resolver
49+
if len(dnsServer) == 0 {
50+
// try from environment if not already set by CLI
51+
dnsServer = os.Getenv("SRV_DNS")
52+
}
53+
if len(dnsServer) != 0 {
54+
// check addr:port form is valid
55+
_, _, err := net.SplitHostPort(dnsServer)
56+
if err != nil {
57+
fmt.Fprintf(os.Stderr, "error: %v\n", err)
58+
os.Exit(1)
59+
}
60+
}
61+
62+
// lookup the services
63+
services := pflag.Args()
64+
if len(services) == 0 {
65+
fmt.Fprintf(os.Stderr, usageFormatShort, os.Args[0])
66+
fmt.Fprintf(os.Stderr, "\ntry %s --help\n", os.Args[0])
67+
os.Exit(0)
68+
}
69+
for _, service := range services {
70+
if len(dnsServer) != 0 {
71+
records, err := lookup.LookupSRVCustom(service, dnsServer, recurse)
72+
if err != nil {
73+
fmt.Fprintf(os.Stderr, "%v\n", err)
74+
continue
75+
}
76+
for _, record := range records {
77+
fmt.Printf("%s:%d\n", record.Target, record.Port)
78+
}
79+
} else {
80+
records, err := lookup.LookupSRVSystem(service, recurse)
81+
if err != nil {
82+
fmt.Fprintf(os.Stderr, "%v\n", err)
83+
continue
84+
}
85+
for _, record := range records {
86+
fmt.Printf("%s:%d\n", record.Target, record.Port)
87+
}
88+
}
89+
}
90+
}

go.mod

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module neomantra/srv-plz
2+
3+
go 1.17
4+
5+
require (
6+
github.com/miekg/dns v1.1.46
7+
github.com/spf13/pflag v1.0.5
8+
)
9+
10+
require (
11+
golang.org/x/mod v0.4.2 // indirect
12+
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985 // indirect
13+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
14+
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect
15+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
16+
)

go.sum

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
github.com/miekg/dns v1.1.46 h1:uzwpxRtSVxtcIZmz/4Uz6/Rn7G11DvsaslXoy5LxQio=
2+
github.com/miekg/dns v1.1.46/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
3+
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
4+
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
5+
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
6+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
7+
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
8+
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
9+
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
10+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
11+
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
12+
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
13+
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985 h1:4CSI6oo7cOjJKajidEljs9h+uP0rRZBPPPhcCbj5mw8=
14+
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
15+
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
16+
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
17+
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
18+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
19+
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
20+
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
21+
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
22+
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
23+
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
24+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
25+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
26+
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
27+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
28+
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
29+
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
30+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
31+
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
32+
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 h1:BonxutuHCTL0rBDnZlKjpGIQFTjyUVTexFOdWkB6Fg0=
33+
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
34+
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
35+
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
36+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
37+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

0 commit comments

Comments
 (0)