diff options
author | Christopher Speller <crspeller@gmail.com> | 2017-05-17 16:51:25 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-17 16:51:25 -0400 |
commit | d103ed6ca97ca5a2669f6cf5fe4b3d2a9c945f26 (patch) | |
tree | dbde13123c6add150448f7b75753ac022d862475 /vendor/github.com/hashicorp/go-sockaddr/cmd/sockaddr/command/dump.go | |
parent | cd23b8139a9463b67e3096744321f6f4eb0ca40a (diff) | |
download | chat-d103ed6ca97ca5a2669f6cf5fe4b3d2a9c945f26.tar.gz chat-d103ed6ca97ca5a2669f6cf5fe4b3d2a9c945f26.tar.bz2 chat-d103ed6ca97ca5a2669f6cf5fe4b3d2a9c945f26.zip |
Upgrading server dependancies (#6431)
Diffstat (limited to 'vendor/github.com/hashicorp/go-sockaddr/cmd/sockaddr/command/dump.go')
-rw-r--r-- | vendor/github.com/hashicorp/go-sockaddr/cmd/sockaddr/command/dump.go | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/go-sockaddr/cmd/sockaddr/command/dump.go b/vendor/github.com/hashicorp/go-sockaddr/cmd/sockaddr/command/dump.go new file mode 100644 index 000000000..a5618b357 --- /dev/null +++ b/vendor/github.com/hashicorp/go-sockaddr/cmd/sockaddr/command/dump.go @@ -0,0 +1,274 @@ +package command + +import ( + "flag" + "fmt" + + "github.com/hashicorp/errwrap" + sockaddr "github.com/hashicorp/go-sockaddr" + "github.com/mitchellh/cli" + "github.com/ryanuber/columnize" +) + +type DumpCommand struct { + Ui cli.Ui + + // attrNames is a list of attribute names to include in the output + attrNames []string + + // flags is a list of options belonging to this command + flags *flag.FlagSet + + // machineMode changes the output format to be machine friendly + // (i.e. tab-separated values). + machineMode bool + + // valueOnly changes the output format to include only values + valueOnly bool + + // ifOnly parses the input as an interface name + ifOnly bool + + // ipOnly parses the input as an IP address (either IPv4 or IPv6) + ipOnly bool + + // v4Only parses the input exclusively as an IPv4 address + v4Only bool + + // v6Only parses the input exclusively as an IPv6 address + v6Only bool + + // unixOnly parses the input exclusively as a UNIX Socket + unixOnly bool +} + +// Description is the long-form command help. +func (c *DumpCommand) Description() string { + return `Parse address(es) or interface and dumps various output.` +} + +// Help returns the full help output expected by `sockaddr -h cmd` +func (c *DumpCommand) Help() string { + return MakeHelp(c) +} + +// InitOpts is responsible for setup of this command's configuration via the +// command line. InitOpts() does not parse the arguments (see parseOpts()). +func (c *DumpCommand) InitOpts() { + c.flags = flag.NewFlagSet("dump", flag.ContinueOnError) + c.flags.Usage = func() { c.Ui.Output(c.Help()) } + c.flags.BoolVar(&c.machineMode, "H", false, "Machine readable output") + c.flags.BoolVar(&c.valueOnly, "n", false, "Show only the value") + c.flags.BoolVar(&c.v4Only, "4", false, "Parse the input as IPv4 only") + c.flags.BoolVar(&c.v6Only, "6", false, "Parse the input as IPv6 only") + c.flags.BoolVar(&c.ifOnly, "I", false, "Parse the argument as an interface name") + c.flags.BoolVar(&c.ipOnly, "i", false, "Parse the input as IP address (either IPv4 or IPv6)") + c.flags.BoolVar(&c.unixOnly, "u", false, "Parse the input as a UNIX Socket only") + c.flags.Var((*MultiArg)(&c.attrNames), "o", "Name of an attribute to pass through") +} + +// Run executes this command. +func (c *DumpCommand) Run(args []string) int { + if len(args) == 0 { + c.Ui.Error(c.Help()) + return 1 + } + + c.InitOpts() + addrs, err := c.parseOpts(args) + if err != nil { + if errwrap.Contains(err, "flag: help requested") { + return 0 + } + return 1 + } + for _, addr := range addrs { + var sa sockaddr.SockAddr + var ifAddrs sockaddr.IfAddrs + var err error + switch { + case c.v4Only: + sa, err = sockaddr.NewIPv4Addr(addr) + case c.v6Only: + sa, err = sockaddr.NewIPv6Addr(addr) + case c.unixOnly: + sa, err = sockaddr.NewUnixSock(addr) + case c.ipOnly: + sa, err = sockaddr.NewIPAddr(addr) + case c.ifOnly: + ifAddrs, err = sockaddr.GetAllInterfaces() + if err != nil { + break + } + + ifAddrs, _, err = sockaddr.IfByName(addr, ifAddrs) + default: + sa, err = sockaddr.NewSockAddr(addr) + } + if err != nil { + c.Ui.Error(fmt.Sprintf("Unable to parse %+q: %v", addr, err)) + return 1 + } + if sa != nil { + c.dumpSockAddr(sa) + } else if ifAddrs != nil { + c.dumpIfAddrs(ifAddrs) + } else { + panic("bad") + } + } + return 0 +} + +// Synopsis returns a terse description used when listing sub-commands. +func (c *DumpCommand) Synopsis() string { + return `Parses input as an IP or interface name(s) and dumps various information` +} + +// Usage is the one-line usage description +func (c *DumpCommand) Usage() string { + return `sockaddr dump [options] input [...]` +} + +// VisitAllFlags forwards the visitor function to the FlagSet +func (c *DumpCommand) VisitAllFlags(fn func(*flag.Flag)) { + c.flags.VisitAll(fn) +} + +func (c *DumpCommand) dumpIfAddrs(ifAddrs sockaddr.IfAddrs) { + for _, ifAddr := range ifAddrs { + c.dumpSockAddr(ifAddr.SockAddr) + } +} + +func (c *DumpCommand) dumpSockAddr(sa sockaddr.SockAddr) { + reservedAttrs := []sockaddr.AttrName{"Attribute"} + const maxNumAttrs = 32 + + output := make([]string, 0, maxNumAttrs+len(reservedAttrs)) + allowedAttrs := make(map[sockaddr.AttrName]struct{}, len(c.attrNames)+len(reservedAttrs)) + for _, attr := range reservedAttrs { + allowedAttrs[attr] = struct{}{} + } + for _, attr := range c.attrNames { + allowedAttrs[sockaddr.AttrName(attr)] = struct{}{} + } + + // allowedAttr returns true if the attribute is allowed to be appended + // to the output. + allowedAttr := func(k sockaddr.AttrName) bool { + if len(allowedAttrs) == len(reservedAttrs) { + return true + } + + _, found := allowedAttrs[k] + return found + } + + // outFmt is a small helper function to reduce the tedium below. outFmt + // returns a new slice and expects the value to already be a string. + outFmt := func(o []string, k sockaddr.AttrName, v interface{}) []string { + if !allowedAttr(k) { + return o + } + switch { + case c.valueOnly: + return append(o, fmt.Sprintf("%s", v)) + case !c.valueOnly && c.machineMode: + return append(o, fmt.Sprintf("%s\t%s", k, v)) + case !c.valueOnly && !c.machineMode: + fallthrough + default: + return append(o, fmt.Sprintf("%s | %s", k, v)) + } + } + + if !c.machineMode { + output = outFmt(output, "Attribute", "Value") + } + + // Attributes for all SockAddr types + for _, attr := range sockaddr.SockAddrAttrs() { + output = outFmt(output, attr, sockaddr.SockAddrAttr(sa, attr)) + } + + // Attributes for all IP types (both IPv4 and IPv6) + if sa.Type()&sockaddr.TypeIP != 0 { + ip := *sockaddr.ToIPAddr(sa) + for _, attr := range sockaddr.IPAttrs() { + output = outFmt(output, attr, sockaddr.IPAddrAttr(ip, attr)) + } + } + + if sa.Type() == sockaddr.TypeIPv4 { + ipv4 := *sockaddr.ToIPv4Addr(sa) + for _, attr := range sockaddr.IPv4Attrs() { + output = outFmt(output, attr, sockaddr.IPv4AddrAttr(ipv4, attr)) + } + } + + if sa.Type() == sockaddr.TypeIPv6 { + ipv6 := *sockaddr.ToIPv6Addr(sa) + for _, attr := range sockaddr.IPv6Attrs() { + output = outFmt(output, attr, sockaddr.IPv6AddrAttr(ipv6, attr)) + } + } + + if sa.Type() == sockaddr.TypeUnix { + us := *sockaddr.ToUnixSock(sa) + for _, attr := range sockaddr.UnixSockAttrs() { + output = outFmt(output, attr, sockaddr.UnixSockAttr(us, attr)) + } + } + + // Developer-focused arguments + { + arg1, arg2 := sa.DialPacketArgs() + output = outFmt(output, "DialPacket", fmt.Sprintf("%+q %+q", arg1, arg2)) + } + { + arg1, arg2 := sa.DialStreamArgs() + output = outFmt(output, "DialStream", fmt.Sprintf("%+q %+q", arg1, arg2)) + } + { + arg1, arg2 := sa.ListenPacketArgs() + output = outFmt(output, "ListenPacket", fmt.Sprintf("%+q %+q", arg1, arg2)) + } + { + arg1, arg2 := sa.ListenStreamArgs() + output = outFmt(output, "ListenStream", fmt.Sprintf("%+q %+q", arg1, arg2)) + } + + result := columnize.SimpleFormat(output) + c.Ui.Output(result) +} + +// parseOpts is responsible for parsing the options set in InitOpts(). Returns +// a list of non-parsed flags. +func (c *DumpCommand) parseOpts(args []string) ([]string, error) { + if err := c.flags.Parse(args); err != nil { + return nil, err + } + + conflictingOptsCount := 0 + if c.v4Only { + conflictingOptsCount++ + } + if c.v6Only { + conflictingOptsCount++ + } + if c.unixOnly { + conflictingOptsCount++ + } + if c.ifOnly { + conflictingOptsCount++ + } + if c.ipOnly { + conflictingOptsCount++ + } + if conflictingOptsCount > 1 { + return nil, fmt.Errorf("Conflicting options specified, only one parsing mode may be specified at a time") + } + + return c.flags.Args(), nil +} |