Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add plural helpers #11

Merged
merged 3 commits into from
May 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions Makefile → GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ TOOLS= golang.org/x/tools/cover
GOCOVER_TMPFILE?= $(GOCOVER_FILE).tmp
GOCOVER_FILE?= .cover.out
GOCOVERHTML?= coverage.html
FIND=`/usr/bin/which 2> /dev/null gfind find | /usr/bin/grep -v ^no | /usr/bin/head -n 1`
XARGS=`/usr/bin/which 2> /dev/null gxargs xargs | /usr/bin/grep -v ^no | /usr/bin/head -n 1`

test:: $(GOCOVER_FILE)
@$(MAKE) -C cmd/sockaddr test

cover:: coverage_report

$(GOCOVER_FILE)::
@find . -type d ! -path '*cmd*' ! -path '*.git*' -print0 | xargs -0 -I % sh -ec "cd % && rm -f $(GOCOVER_TMPFILE) && go test -coverprofile=$(GOCOVER_TMPFILE)"
@${FIND} . -type d ! -path '*cmd*' ! -path '*.git*' -print0 | ${XARGS} -0 -I % sh -ec "cd % && rm -f $(GOCOVER_TMPFILE) && go test -coverprofile=$(GOCOVER_TMPFILE)"

@echo 'mode: set' > $(GOCOVER_FILE)
@find . -type f ! -path '*cmd*' ! -path '*.git*' -name "$(GOCOVER_TMPFILE)" -print0 | xargs -0 -n1 cat $(GOCOVER_TMPFILE) | grep -v '^mode: ' >> ${PWD}/$(GOCOVER_FILE)
@${FIND} . -type f ! -path '*cmd*' ! -path '*.git*' -name "$(GOCOVER_TMPFILE)" -print0 | ${XARGS} -0 -n1 cat $(GOCOVER_TMPFILE) | grep -v '^mode: ' >> ${PWD}/$(GOCOVER_FILE)

$(GOCOVERHTML): $(GOCOVER_FILE)
go tool cover -html=$(GOCOVER_FILE) -o $(GOCOVERHTML)
Expand Down Expand Up @@ -41,15 +43,15 @@ clean::

dev::
@go build
@make -B -C cmd/sockaddr sockaddr
@$(MAKE) -B -C cmd/sockaddr sockaddr

install::
@go install
@make -C cmd/sockaddr install
@$(MAKE) -C cmd/sockaddr install

doc::
echo Visit: http://127.0.0.1:6060/pkg/github.com/hashicorp/go-sockaddr/
godoc -http=:6060 -goroot $GOROOT
@echo Visit: http://127.0.0.1:6161/pkg/github.com/hashicorp/go-sockaddr/
godoc -http=:6161 -goroot $GOROOT

world::
@set -e; \
Expand All @@ -60,4 +62,4 @@ world::
done; \
done

make -C cmd/sockaddr world
$(MAKE) -C cmd/sockaddr world
2 changes: 1 addition & 1 deletion cmd/sockaddr/GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ install:: $(BIN)

.PHONY: test
test:: $(BIN)
@make -C regression
@$(MAKE) -C regression

.PHONY: world
world::
Expand Down
128 changes: 128 additions & 0 deletions ifaddr.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package sockaddr

import "strings"

// ifAddrAttrMap is a map of the IfAddr type-specific attributes.
var ifAddrAttrMap map[AttrName]func(IfAddr) string
var ifAddrAttrs []AttrName
Expand Down Expand Up @@ -30,6 +32,53 @@ func GetPrivateIP() (string, error) {
return ip.NetIP().String(), nil
}

// GetPrivateIPs returns a string with all IP addresses that are part of RFC
// 6890 (regardless of whether or not there is a default route, unlike
// GetPublicIP). If the system can't find any RFC 6890 IP addresses, an empty
// string will be returned instead. This function is the `eval` equivalent of:
//
// ```
// $ sockaddr eval -r '{{GetAllInterfaces | include "RFC" "6890" | join "address" " "}}'
/// ```
func GetPrivateIPs() (string, error) {
ifAddrs, err := GetAllInterfaces()
if err != nil {
return "", err
} else if len(ifAddrs) < 1 {
return "", nil
}

ifAddrs, _ = FilterIfByType(ifAddrs, TypeIP)
if len(ifAddrs) == 0 {
return "", nil
}

OrderedIfAddrBy(AscIfType, AscIfNetworkSize).Sort(ifAddrs)

ifAddrs, _, err = IfByRFC("6890", ifAddrs)
if err != nil {
return "", err
} else if len(ifAddrs) == 0 {
return "", nil
}

_, ifAddrs, err = IfByRFC(ForwardingBlacklistRFC, ifAddrs)
if err != nil {
return "", err
} else if len(ifAddrs) == 0 {
return "", nil
}

ips := make([]string, 0, len(ifAddrs))
for _, ifAddr := range ifAddrs {
ip := *ToIPAddr(ifAddr.SockAddr)
s := ip.NetIP().String()
ips = append(ips, s)
}

return strings.Join(ips, " "), nil
}

// GetPublicIP returns a string with a single IP address that is NOT part of RFC
// 6890 and has a default route. If the system can't determine its IP address
// or find a non RFC 6890 IP address, an empty string will be returned instead.
Expand All @@ -51,6 +100,47 @@ func GetPublicIP() (string, error) {
return ip.NetIP().String(), nil
}

// GetPublicIPs returns a string with all IP addresses that are NOT part of RFC
// 6890 (regardless of whether or not there is a default route, unlike
// GetPublicIP). If the system can't find any non RFC 6890 IP addresses, an
// empty string will be returned instead. This function is the `eval`
// equivalent of:
//
// ```
// $ sockaddr eval -r '{{GetAllInterfaces | exclude "RFC" "6890" | join "address" " "}}'
/// ```
func GetPublicIPs() (string, error) {
ifAddrs, err := GetAllInterfaces()
if err != nil {
return "", err
} else if len(ifAddrs) < 1 {
return "", nil
}

ifAddrs, _ = FilterIfByType(ifAddrs, TypeIP)
if len(ifAddrs) == 0 {
return "", nil
}

OrderedIfAddrBy(AscIfType, AscIfNetworkSize).Sort(ifAddrs)

_, ifAddrs, err = IfByRFC("6890", ifAddrs)
if err != nil {
return "", err
} else if len(ifAddrs) == 0 {
return "", nil
}

ips := make([]string, 0, len(ifAddrs))
for _, ifAddr := range ifAddrs {
ip := *ToIPAddr(ifAddr.SockAddr)
s := ip.NetIP().String()
ips = append(ips, s)
}

return strings.Join(ips, " "), nil
}

// GetInterfaceIP returns a string with a single IP address sorted by the size
// of the network (i.e. IP addresses with a smaller netmask, larger network
// size, are sorted first). This function is the `eval` equivalent of:
Expand Down Expand Up @@ -91,6 +181,44 @@ func GetInterfaceIP(namedIfRE string) (string, error) {
return IPAddrAttr(*ip, "address"), nil
}

// GetInterfaceIPs returns a string with all IPs, sorted by the size of the
// network (i.e. IP addresses with a smaller netmask, larger network size, are
// sorted first), on a named interface. This function is the `eval` equivalent
// of:
//
// ```
// $ sockaddr eval -r '{{GetAllInterfaces | include "name" <<ARG>> | sort "type,size" | join "address" " "}}'
/// ```
func GetInterfaceIPs(namedIfRE string) (string, error) {
ifAddrs, err := GetAllInterfaces()
if err != nil {
return "", err
}

ifAddrs, _, err = IfByName(namedIfRE, ifAddrs)
if err != nil {
return "", err
}

ifAddrs, err = SortIfBy("+type,+size", ifAddrs)
if err != nil {
return "", err
}

if len(ifAddrs) == 0 {
return "", err
}

ips := make([]string, 0, len(ifAddrs))
for _, ifAddr := range ifAddrs {
ip := *ToIPAddr(ifAddr.SockAddr)
s := ip.NetIP().String()
ips = append(ips, s)
}

return strings.Join(ips, " "), nil
}

// IfAddrAttrs returns a list of attributes supported by the IfAddr type
func IfAddrAttrs() []AttrName {
return ifAddrAttrs
Expand Down
54 changes: 54 additions & 0 deletions ifaddr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,42 @@ func havePublicIP() bool {
return boolEnvVar("SOCKADDR_HAVE_PUBLIC_IP", false)
}

func TestGetPrivateIP(t *testing.T) {
reportOnPrivate := func(args ...interface{}) {
if havePrivateIP() {
t.Fatalf(args[0].(string), args[1:]...)
} else {
t.Skipf(args[0].(string), args[1:]...)
}
}
ip, err := sockaddr.GetPrivateIP()
if err != nil {
reportOnPrivate("unable to get a private IP: %v", err)
}

if ip == "" {
reportOnPrivate("it's hard to test this reliably")
}
}

func TestGetPrivateIPs(t *testing.T) {
reportOnPrivate := func(args ...interface{}) {
if havePrivateIP() {
t.Fatalf(args[0].(string), args[1:]...)
} else {
t.Skipf(args[0].(string), args[1:]...)
}
}
ips, err := sockaddr.GetPrivateIPs()
if err != nil {
reportOnPrivate("unable to get a private IPs: %v", err)
}

if ips == "" {
reportOnPrivate("it's hard to test this reliably")
}
}

func TestGetPublicIP(t *testing.T) {
reportOnPublic := func(args ...interface{}) {
if havePublicIP() {
Expand All @@ -63,6 +99,24 @@ func TestGetPublicIP(t *testing.T) {
}
}

func TestGetPublicIPs(t *testing.T) {
reportOnPublic := func(args ...interface{}) {
if havePublicIP() {
t.Fatalf(args[0].(string), args[1:]...)
} else {
t.Skipf(args[0].(string), args[1:]...)
}
}
ips, err := sockaddr.GetPublicIPs()
if err != nil {
reportOnPublic("unable to get a public IPs: %v", err)
}

if ips == "" {
reportOnPublic("it's hard to test this reliably")
}
}

func TestGetInterfaceIP(t *testing.T) {
ip, err := sockaddr.GetInterfaceIP(`^.*[\d]$`)
if err != nil {
Expand Down
21 changes: 1 addition & 20 deletions ifaddrs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -697,25 +697,6 @@ func TestGetDefaultInterface(t *testing.T) {
}
}

func TestGetPrivateIP(t *testing.T) {
reportOnPrivate := func(args ...interface{}) {
if havePrivateIP() {
t.Fatalf(args[0].(string), args[1:]...)
} else {
t.Skipf(args[0].(string), args[1:]...)
}
}

ip, err := sockaddr.GetPrivateIP()
if err != nil {
reportOnPrivate("private IP failed: %v", err)
}

if len(ip) == 0 {
reportOnPrivate("no private IP found", nil)
}
}

func TestIfAddrAttrs(t *testing.T) {
const expectedNumAttrs = 2
attrs := sockaddr.IfAddrAttrs()
Expand Down Expand Up @@ -838,7 +819,7 @@ func TestGetPrivateInterfaces(t *testing.T) {
}

if len(ifAddrs) == 0 {
reportOnPrivate("no public IPs found", nil)
reportOnPrivate("no public IPs found")
}

if len(ifAddrs[0].String()) == 0 {
Expand Down
1 change: 1 addition & 0 deletions rfc.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package sockaddr
// ForwardingBlacklist is a faux RFC that includes a list of non-forwardable IP
// blocks.
const ForwardingBlacklist = 4294967295
const ForwardingBlacklistRFC = "4294967295"

// IsRFC tests to see if an SockAddr matches the specified RFC
func IsRFC(rfcNum uint, sa SockAddr) bool {
Expand Down
File renamed without changes.
27 changes: 26 additions & 1 deletion template/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,44 @@ Example:
{{ GetPrivateIP }}


`GetPrivateIPs` - Helper function that returns a string of the all private IP
addresses on the host.

Example:

{{ GetPrivateIPs }}


`GetPublicIP` - Helper function that returns a string of the first IP from
GetPublicInterfaces.

Example:

{{ GetPublicIP }}

`GetPublicIPs` - Helper function that returns a space-delimited string of the
all public IP addresses on the host.

Example:

{{ GetPrivateIPs }}


`GetInterfaceIP` - Helper function that returns a string of the first IP from
the named interface.

Example:

{{ GetInterfaceIP "eth1" }}
{{ GetInterfaceIP "en0" }}



`GetInterfaceIPs` - Helper function that returns a space-delimited list of all
IPs on a given interface.

Example:

{{ GetInterfaceIPs "en0" }}


`sort` - Sorts the IfAddrs result based on its arguments. `sort` takes one
Expand Down
14 changes: 14 additions & 0 deletions template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,27 @@ func init() {
// to the default route and a forwardable address.
"GetPrivateIP": sockaddr.GetPrivateIP,

// Return all Private RFC 6890 IP addresses as a space-delimited string of
// IP addresses. Addresses returned do not have to be on the interface with
// a default route.
"GetPrivateIPs": sockaddr.GetPrivateIPs,

// Return a Public RFC 6890 IP address string that is attached
// to the default route and a forwardable address.
"GetPublicIP": sockaddr.GetPublicIP,

// Return allPublic RFC 6890 IP addresses as a space-delimited string of IP
// addresses. Addresses returned do not have to be on the interface with a
// default route.
"GetPublicIPs": sockaddr.GetPublicIPs,

// Return the first IP address of the named interface, sorted by
// the largest network size.
"GetInterfaceIP": sockaddr.GetInterfaceIP,

// Return all IP addresses on the named interface, sorted by the largest
// network size.
"GetInterfaceIPs": sockaddr.GetInterfaceIPs,
}
}

Expand Down
Loading