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/template | |
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/template')
5 files changed, 575 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/go-sockaddr/template/Makefile b/vendor/github.com/hashicorp/go-sockaddr/template/Makefile new file mode 100644 index 000000000..ce1e274e4 --- /dev/null +++ b/vendor/github.com/hashicorp/go-sockaddr/template/Makefile @@ -0,0 +1,2 @@ +test:: + go test diff --git a/vendor/github.com/hashicorp/go-sockaddr/template/README.md b/vendor/github.com/hashicorp/go-sockaddr/template/README.md new file mode 100644 index 000000000..c40905af7 --- /dev/null +++ b/vendor/github.com/hashicorp/go-sockaddr/template/README.md @@ -0,0 +1,6 @@ +# sockaddr/template + +sockaddr's template library. See +the +[sockaddr/template](https://godoc.org/github.com/hashicorp/go-sockaddr/template) +docs for details on how to use this template. diff --git a/vendor/github.com/hashicorp/go-sockaddr/template/doc.go b/vendor/github.com/hashicorp/go-sockaddr/template/doc.go new file mode 100644 index 000000000..59945d7be --- /dev/null +++ b/vendor/github.com/hashicorp/go-sockaddr/template/doc.go @@ -0,0 +1,239 @@ +/* + +Package sockaddr/template provides a text/template interface the SockAddr helper +functions. The primary entry point into the sockaddr/template package is +through its Parse() call. For example: + + import ( + "fmt" + + template "github.com/hashicorp/go-sockaddr/template" + ) + + results, err := template.Parse(`{{ GetPrivateIP }}`) + if err != nil { + fmt.Errorf("Unable to find a private IP address: %v", err) + } + fmt.Printf("My Private IP address is: %s\n", results) + +Below is a list of builtin template functions and details re: their usage. It +is possible to add additional functions by calling ParseIfAddrsTemplate +directly. + +In general, the calling convention for this template library is to seed a list +of initial interfaces via one of the Get*Interfaces() calls, then filter, sort, +and extract the necessary attributes for use as string input. This template +interface is primarily geared toward resolving specific values that are only +available at runtime, but can be defined as a heuristic for execution when a +config file is parsed. + +All functions, unless noted otherwise, return an array of IfAddr structs making +it possible to `sort`, `filter`, `limit`, seek (via the `offset` function), or +`unique` the list. To extract useful string information, the `attr` and `join` +functions return a single string value. See below for details. + +Important note: see the +https://github.com/hashicorp/go-sockaddr/tree/master/cmd/sockaddr utility for +more examples and for a CLI utility to experiment with the template syntax. + +`GetAllInterfaces` - Returns an exhaustive set of IfAddr structs available on +the host. `GetAllInterfaces` is the initial input and accessible as the initial +"dot" in the pipeline. + +Example: + + {{ GetAllInterfaces }} + + +`GetDefaultInterfaces` - Returns one IfAddr for every IP that is on the +interface containing the default route for the host. + +Example: + + {{ GetDefaultInterfaces }} + +`GetPrivateInterfaces` - Returns one IfAddr for every forwardable IP address +that is included in RFC 6890, is attached to the interface with the default +route, and whose interface is marked as up. NOTE: RFC 6890 is a more exhaustive +version of RFC1918 because it spans IPv4 and IPv6, however it does permit the +inclusion of likely undesired addresses such as multicast, therefore our version +of "private" also filters out non-forwardable addresses. + +Example: + + {{ GetPrivateInterfaces | include "flags" "up" }} + + +`GetPublicInterfaces` - Returns a list of IfAddr that do not match RFC 6890, is +attached to the default route, and whose interface is marked as up. + +Example: + + {{ GetPublicInterfaces | include "flags" "up" }} + + +`GetPrivateIP` - Helper function that returns a string of the first IP address +from GetPrivateInterfaces. + +Example: + + {{ GetPrivateIP }} + + +`GetPublicIP` - Helper function that returns a string of the first IP from +GetPublicInterfaces. + +Example: + + {{ GetPublicIP }} + +`GetInterfaceIP` - Helper function that returns a string of the first IP from +the named interface. + +Example: + + {{ GetInterfaceIP }} + + +`sort` - Sorts the IfAddrs result based on its arguments. `sort` takes one +argument, a list of ways to sort its IfAddrs argument. The list of sort +criteria is comma separated (`,`): + - `address`, `+address`: Ascending sort of IfAddrs by Address + - `-address`: Descending sort of IfAddrs by Address + - `name`, `+name`: Ascending sort of IfAddrs by lexical ordering of interface name + - `-name`: Descending sort of IfAddrs by lexical ordering of interface name + - `port`, `+port`: Ascending sort of IfAddrs by port number + - `-port`: Descending sort of IfAddrs by port number + - `private`, `+private`: Ascending sort of IfAddrs with private addresses first + - `-private`: Descending sort IfAddrs with private addresses last + - `size`, `+size`: Ascending sort of IfAddrs by their network size as determined + by their netmask (larger networks first) + - `-size`: Descending sort of IfAddrs by their network size as determined by their + netmask (smaller networks first) + - `type`, `+type`: Ascending sort of IfAddrs by the type of the IfAddr (Unix, + IPv4, then IPv6) + - `-type`: Descending sort of IfAddrs by the type of the IfAddr (IPv6, IPv4, Unix) + +Example: + + {{ GetPrivateInterfaces | sort "type,size,address" }} + + +`exclude` and `include`: Filters IfAddrs based on the selector criteria and its +arguments. Both `exclude` and `include` take two arguments. The list of +available filtering criteria is: + - "address": Filter IfAddrs based on a regexp matching the string representation + of the address + - "flag","flags": Filter IfAddrs based on the list of flags specified. Multiple + flags can be passed together using the pipe character (`|`) to create an inclusive + bitmask of flags. The list of flags is included below. + - "name": Filter IfAddrs based on a regexp matching the interface name. + - "network": Filter IfAddrs based on whether a netowkr is included in a given + CIDR. More than one CIDR can be passed in if each network is separated by + the pipe character (`|`). + - "port": Filter IfAddrs based on an exact match of the port number (number must + be expressed as a string) + - "rfc", "rfcs": Filter IfAddrs based on the matching RFC. If more than one RFC + is specified, the list of RFCs can be joined together using the pipe character (`|`). + - "size": Filter IfAddrs based on the exact match of the mask size. + - "type": Filter IfAddrs based on their SockAddr type. Multiple types can be + specified together by using the pipe character (`|`). Valid types include: + `ip`, `ipv4`, `ipv6`, and `unix`. + +Example: + + {{ GetPrivateInterfaces | exclude "type" "IPv6" | include "flag" "up|forwardable" }} + + +`unique`: Removes duplicate entries from the IfAddrs list, assuming the list has +already been sorted. `unique` only takes one argument: + - "address": Removes duplicates with the same address + - "name": Removes duplicates with the same interface names + +Example: + + {{ GetPrivateInterfaces | sort "type,address" | unique "name" }} + + +`limit`: Reduces the size of the list to the specified value. + +Example: + + {{ GetPrivateInterfaces | include "flags" "forwardable|up" | limit 1 }} + + +`offset`: Seeks into the list by the specified value. A negative value can be +used to seek from the end of the list. + +Example: + + {{ GetPrivateInterfaces | include "flags" "forwardable|up" | offset "-2" | limit 1 }} + + +`attr`: Extracts a single attribute of the first member of the list and returns +it as a string. `attr` takes a single attribute name. The list of available +attributes is type-specific and shared between `join`. See below for a list of +supported attributes. + +Example: + + {{ GetPrivateInterfaces | include "flags" "forwardable|up" | attr "address" }} + + +`join`: Similar to `attr`, `join` extracts all matching attributes of the list +and returns them as a string joined by the separator, the second argument to +`join`. The list of available attributes is type-specific and shared between +`join`. + +Example: + + {{ GetPrivateInterfaces | include "flags" "forwardable|up" | join "address" " " }} + + +`exclude` and `include` flags: + - `broadcast` + - `down`: Is the interface down? + - `forwardable`: Is the IP forwardable? + - `global unicast` + - `interface-local multicast` + - `link-local multicast` + - `link-local unicast` + - `loopback` + - `multicast` + - `point-to-point` + - `unspecified`: Is the IfAddr the IPv6 unspecified address? + - `up`: Is the interface up? + + +Attributes for `attr` and `join`: + +SockAddr Type: + - `string` + - `type` + +IPAddr Type: + - `address` + - `binary` + - `first_usable` + - `hex` + - `host` + - `last_usable` + - `mask_bits` + - `netmask` + - `network` + - `octets`: Decimal values per byte + - `port` + - `size`: Number of hosts in the network + +IPv4Addr Type: + - `broadcast` + - `uint32`: unsigned integer representation of the value + +IPv6Addr Type: + - `uint128`: unsigned integer representation of the value + +UnixSock Type: + - `path` + +*/ +package template diff --git a/vendor/github.com/hashicorp/go-sockaddr/template/template.go b/vendor/github.com/hashicorp/go-sockaddr/template/template.go new file mode 100644 index 000000000..ffe467b7f --- /dev/null +++ b/vendor/github.com/hashicorp/go-sockaddr/template/template.go @@ -0,0 +1,125 @@ +package template + +import ( + "bytes" + "fmt" + "text/template" + + "github.com/hashicorp/errwrap" + sockaddr "github.com/hashicorp/go-sockaddr" +) + +var ( + // SourceFuncs is a map of all top-level functions that generate + // sockaddr data types. + SourceFuncs template.FuncMap + + // SortFuncs is a map of all functions used in sorting + SortFuncs template.FuncMap + + // FilterFuncs is a map of all functions used in sorting + FilterFuncs template.FuncMap + + // HelperFuncs is a map of all functions used in sorting + HelperFuncs template.FuncMap +) + +func init() { + SourceFuncs = template.FuncMap{ + // GetAllInterfaces - Returns an exhaustive set of IfAddr + // structs available on the host. `GetAllInterfaces` is the + // initial input and accessible as the initial "dot" in the + // pipeline. + "GetAllInterfaces": sockaddr.GetAllInterfaces, + + // GetDefaultInterfaces - Returns one IfAddr for every IP that + // is on the interface containing the default route for the + // host. + "GetDefaultInterfaces": sockaddr.GetDefaultInterfaces, + + // GetPrivateInterfaces - Returns one IfAddr for every IP that + // matches RFC 6890, are attached to the interface with the + // default route, and are forwardable IP addresses. NOTE: RFC + // 6890 is a more exhaustive version of RFC1918 because it spans + // IPv4 and IPv6, however it doespermit the inclusion of likely + // undesired addresses such as multicast, therefore our + // definition of a "private" address also excludes + // non-forwardable IP addresses (as defined by the IETF). + "GetPrivateInterfaces": sockaddr.GetPrivateInterfaces, + + // GetPublicInterfaces - Returns a list of IfAddr that do not + // match RFC 6890, are attached to the default route, and are + // forwardable. + "GetPublicInterfaces": sockaddr.GetPublicInterfaces, + } + + SortFuncs = template.FuncMap{ + "sort": sockaddr.SortIfBy, + } + + FilterFuncs = template.FuncMap{ + "exclude": sockaddr.ExcludeIfs, + "include": sockaddr.IncludeIfs, + } + + HelperFuncs = template.FuncMap{ + // Misc functions that operate on IfAddrs inputs + "attr": sockaddr.IfAttr, + "join": sockaddr.JoinIfAddrs, + "limit": sockaddr.LimitIfAddrs, + "offset": sockaddr.OffsetIfAddrs, + "unique": sockaddr.UniqueIfAddrsBy, + + // Return a Private RFC 6890 IP address string that is attached + // to the default route and a forwardable address. + "GetPrivateIP": sockaddr.GetPrivateIP, + + // Return a Public RFC 6890 IP address string that is attached + // to the default route and a forwardable address. + "GetPublicIP": sockaddr.GetPublicIP, + + // Return the first IP address of the named interface, sorted by + // the largest network size. + "GetInterfaceIP": sockaddr.GetInterfaceIP, + } +} + +// Parse parses input as template input using the addresses available on the +// host, then returns the string output if there are no errors. +func Parse(input string) (string, error) { + addrs, err := sockaddr.GetAllInterfaces() + if err != nil { + return "", errwrap.Wrapf("unable to query interface addresses: {{err}}", err) + } + + return ParseIfAddrs(input, addrs) +} + +// ParseIfAddrs parses input as template input using the IfAddrs inputs, then +// returns the string output if there are no errors. +func ParseIfAddrs(input string, ifAddrs sockaddr.IfAddrs) (string, error) { + return ParseIfAddrsTemplate(input, ifAddrs, template.New("sockaddr.Parse")) +} + +// ParseIfAddrsTemplate parses input as template input using the IfAddrs inputs, +// then returns the string output if there are no errors. +func ParseIfAddrsTemplate(input string, ifAddrs sockaddr.IfAddrs, tmplIn *template.Template) (string, error) { + // Create a template, add the function map, and parse the text. + tmpl, err := tmplIn.Option("missingkey=error"). + Funcs(SourceFuncs). + Funcs(SortFuncs). + Funcs(FilterFuncs). + Funcs(HelperFuncs). + Parse(input) + if err != nil { + return "", errwrap.Wrapf(fmt.Sprintf("unable to parse template %+q: {{err}}", input), err) + } + + var outWriter bytes.Buffer + err = tmpl.Execute(&outWriter, ifAddrs) + if err != nil { + return "", errwrap.Wrapf(fmt.Sprintf("unable to execute sockaddr input %+q: {{err}}", input), err) + } + + return outWriter.String(), nil +} diff --git a/vendor/github.com/hashicorp/go-sockaddr/template/template_test.go b/vendor/github.com/hashicorp/go-sockaddr/template/template_test.go new file mode 100644 index 000000000..6f2b47828 --- /dev/null +++ b/vendor/github.com/hashicorp/go-sockaddr/template/template_test.go @@ -0,0 +1,203 @@ +package template_test + +import ( + "testing" + + socktmpl "github.com/hashicorp/go-sockaddr/template" +) + +func TestSockAddr_Parse(t *testing.T) { + tests := []struct { + name string + input string + output string + fail bool + requireOnline bool + }{ + { + name: `basic include "name"`, + input: `{{GetAllInterfaces | include "name" "lo0" | printf "%v"}}`, + output: `[127.0.0.1/8 {1 16384 lo0 up|loopback|multicast} ::1 {1 16384 lo0 up|loopback|multicast} fe80::1/64 {1 16384 lo0 up|loopback|multicast}]`, + }, + { + name: "invalid input", + input: `{{`, + output: ``, + fail: true, + }, + { + name: "GetDefaultInterface", + input: `{{GetDefaultInterfaces | include "type" "IPv4" | attr "name" }}`, + output: `en0`, + }, + { + name: `include "name" regexp`, + input: `{{GetAllInterfaces | include "name" "^(en|lo)0$" | exclude "name" "^en0$" | sort "type" | sort "address" | join "address" " " }}`, + output: `127.0.0.1 ::1 fe80::1`, + }, + { + name: `exclude "name"`, + input: `{{. | include "name" "^(en|lo)0$" | exclude "name" "^en0$" | sort "type" | sort "address" | join "address" " " }}`, + output: `127.0.0.1 ::1 fe80::1`, + }, + { + name: `"dot" pipeline, IPv4 type`, + input: `{{. | include "type" "IPv4" | include "name" "^lo0$" | sort "type" | sort "address" }}`, + output: `[127.0.0.1/8 {1 16384 lo0 up|loopback|multicast}]`, + }, + { + name: `include "type" "IPv6`, + input: `{{. | include "type" "IPv6" | include "name" "^lo0$" | sort "address" }}`, + output: `[::1 {1 16384 lo0 up|loopback|multicast} fe80::1/64 {1 16384 lo0 up|loopback|multicast}]`, + }, + { + name: "better example for IP types", + input: `{{. | include "type" "IPv4|IPv6" | include "name" "^lo0$" | sort "type" | sort "address" }}`, + output: `[127.0.0.1/8 {1 16384 lo0 up|loopback|multicast} ::1 {1 16384 lo0 up|loopback|multicast} fe80::1/64 {1 16384 lo0 up|loopback|multicast}]`, + }, + { + name: "ifAddrs1", + input: `{{. | include "type" "IPv4" | include "name" "^lo0$"}}`, + output: `[127.0.0.1/8 {1 16384 lo0 up|loopback|multicast}]`, + }, + { + name: "ifAddrs2", + input: `{{. | include "type" "IP" | include "name" "^lo0$" | sort "type" | sort "address" }}`, + output: `[127.0.0.1/8 {1 16384 lo0 up|loopback|multicast} ::1 {1 16384 lo0 up|loopback|multicast} fe80::1/64 {1 16384 lo0 up|loopback|multicast}]`, + }, + { + name: `range "dot" example`, + input: `{{range . | include "type" "IP" | include "name" "^lo0$"}}{{.Name}} {{.SockAddr}} {{end}}`, + output: `lo0 127.0.0.1/8 lo0 ::1 lo0 fe80::1/64 `, + }, + { + name: `exclude "type"`, + input: `{{. | exclude "type" "IPv4" | include "name" "^lo0$" | sort "address" | unique "name" | join "name" " "}} {{range . | exclude "type" "IPv4" | include "name" "^lo0$"}}{{.SockAddr}} {{end}}`, + output: `lo0 ::1 fe80::1/64 `, + }, + { + name: "with variable pipeline", + input: `{{with $ifSet := include "type" "IPv4" . | include "name" "^lo0$"}}{{range $ifSet }}{{.Name}} {{end}}{{range $ifSet}}{{.SockAddr}} {{end}}{{end}}`, + output: `lo0 127.0.0.1/8 `, + }, + { + name: "range sample on lo0", + input: `{{with $ifAddrs := . | exclude "rfc" "1918" | include "name" "lo0" | sort "type,address" }}{{range $ifAddrs }}{{.Name}}/{{.SockAddr.NetIP}} {{end}}{{end}}`, + output: `lo0/127.0.0.1 lo0/::1 lo0/fe80::1 `, + }, + { + name: "non-RFC1918 on on lo0", + input: `{{. | exclude "rfc" "1918" | include "name" "lo0" | sort "type,address" | len | eq 3}}`, + output: `true`, + }, + { + // NOTE(sean@): Difficult to reliably test includeByRFC. + // In this case, we ass-u-me that the host running the + // test has at least one RFC1918 address on their host. + name: `include "rfc"`, + input: `{{(. | include "rfc" "1918" | attr "name")}}`, + output: `en0`, + requireOnline: true, + }, + { + name: "test for non-empty array", + input: `{{. | include "type" "IPv4" | include "rfc" "1918" | print | len | eq (len "[]")}}`, + output: `false`, + }, + { + // NOTE(sean@): This will fail if there is a public IPv4 address on loopback. + name: "non-IPv4 RFC1918", + input: `{{. | include "name" "lo0" | exclude "type" "IPv4" | include "rfc" "1918" | len | eq 0}}`, + output: `true`, + }, + { + // NOTE(sean@): There are no RFC6598 addresses on most testing hosts so this should be empty. + name: "rfc6598", + input: `{{. | include "type" "IPv4" | include "rfc" "6598" | print | len | eq (len "[]")}}`, + output: `true`, + }, + { + name: "invalid RFC", + input: `{{. | include "type" "IPv4" | include "rfc" "99999999999" | print | len | eq (len "[]")}}`, + output: `true`, + fail: true, + }, + { + name: `sort asc address`, + input: `{{ . | include "name" "lo0" | sort "type,address" | join "address" " " }}`, + output: `127.0.0.1 ::1 fe80::1`, + }, + { + name: `sort asc address old`, + input: `{{with $ifSet := include "name" "lo0" . }}{{ range include "type" "IPv4" $ifSet | sort "address"}}{{ .SockAddr }} {{end}}{{ range include "type" "IPv6" $ifSet | sort "address"}}{{ .SockAddr }} {{end}}{{end}}`, + output: `127.0.0.1/8 ::1 fe80::1/64 `, + }, + { + name: `sort desc address`, + input: `{{ . | include "name" "lo0" | sort "type,-address" | join "address" " " }}`, + output: `127.0.0.1 fe80::1 ::1`, + }, + { + name: `sort desc address`, + input: `{{ . | include "name" "lo0" | include "type" "IPv6" | sort "type,-address" | join "address" " " }}`, + output: `fe80::1 ::1`, + }, + { + name: `sort asc address`, + input: `{{with $ifSet := include "name" "lo0" . }}{{ range include "type" "IPv6" $ifSet | sort "address"}}{{ .SockAddr }} {{end}}{{end}}`, + output: `::1 fe80::1/64 `, + }, + { + name: "lo0 limit 1", + input: `{{. | include "name" "lo0" | include "type" "IPv6" | sort "address" | limit 1 | len}}`, + output: `1`, + }, + { + name: "join address", + input: `{{. | include "name" "lo0" | include "type" "IPv6" | sort "address" | join "address" " " }}`, + output: `::1 fe80::1`, + }, + { + name: "join name", + input: `{{. | include "name" "lo0" | include "type" "IPv6" | sort "address" | join "name" " " }}`, + output: `lo0 lo0`, + }, + { + name: "lo0 flags up and limit 1", + input: `{{. | include "name" "lo0" | include "flag" "up" | sort "-type,+address" | attr "address" }}`, + output: `::1`, + }, + { + // NOTE(sean@): This is the HashiCorp default in 2016. + // Indented for effect. Using "true" as the output + // instead of printing the correct $rfc*Addrs values. + name: "HashiCorpDefault2016", + input: ` +{{- with $addr := GetAllInterfaces | include "type" "IP" | include "rfc" "1918|6598" | sort "address" | attr "address" -}} + + {{- if ($addr | len) gt 0 -}} + {{- print "true" -}}{{/* print $addr*/ -}} + {{- end -}} +{{- end -}}`, + output: `true`, + }, + } + + for i, test := range tests { + test := test // capture range variable + if test.name == "" { + t.Fatalf("test number %d has an empty test name", i) + } + t.Run(test.name, func(t *testing.T) { + t.Parallel() + out, err := socktmpl.Parse(test.input) + if err != nil && !test.fail { + t.Fatalf("%q: bad: %v", test.name, err) + } + + if out != test.output && !test.fail { + t.Fatalf("%q: Expected %+q, received %+q\n%+q", test.name, test.output, out, test.input) + } + }) + } +} |