diff --git a/hack/vendor.sh b/hack/vendor.sh index 68db3d5517..630b3388d6 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -25,7 +25,7 @@ clone git golang.org/x/sys eb2c74142fd19a79b3f237334c7384d5167b1b46 https://gith clone git github.com/docker/go-units 651fc226e7441360384da338d0fd37f2440ffbe3 clone git github.com/docker/go-connections v0.2.0 clone git github.com/docker/engine-api 9bab0d5b73872e53dfadfa055dcc519e57b09439 -clone git github.com/RackSec/srslog 6eb773f331e46fbba8eecb8e794e635e75fc04de +clone git github.com/RackSec/srslog 259aed10dfa74ea2961eddd1d9847619f6e98837 clone git github.com/imdario/mergo 0.2.1 #get libnetwork packages diff --git a/vendor/src/github.com/RackSec/srslog/.travis.yml b/vendor/src/github.com/RackSec/srslog/.travis.yml index 767c1d811e..4e5c4f0753 100644 --- a/vendor/src/github.com/RackSec/srslog/.travis.yml +++ b/vendor/src/github.com/RackSec/srslog/.travis.yml @@ -4,10 +4,15 @@ group: edge language: go go: - 1.5 +before_install: + - pip install --user codecov script: - | go get ./... - go test -v ./... + go test -v -coverprofile=coverage.txt -covermode=atomic + go vet +after_success: + - codecov notifications: slack: secure: dtDue9gP6CRR1jYjEf6raXXFak3QKGcCFvCf5mfvv5XScdpmc3udwgqc5TdyjC0goaC9OK/4jTcCD30dYZm/u6ux3E9mo3xwMl2xRLHx76p5r9rSQtloH19BDwA2+A+bpDfFQVz05k2YXuTiGSvNMMdwzx+Dr294Sl/z43RFB4+b9/R/6LlFpRW89IwftvpLAFnBy4K/ZcspQzKM+rQfQTL5Kk+iZ/KBsuR/VziDq6MoJ8t43i4ee8vwS06vFBKDbUiZ4FIZpLgc2RAL5qso5aWRKYXL6waXfoKHZWKPe0w4+9IY1rDJxG1jEb7YGgcbLaF9xzPRRs2b2yO/c87FKpkh6PDgYHfLjpgXotCoojZrL4p1x6MI1ldJr3NhARGPxS9r4liB9n6Y5nD+ErXi1IMf55fuUHcPY27Jc0ySeLFeM6cIWJ8OhFejCgGw6a5DnnmJo0PqopsaBDHhadpLejT1+K6bL2iGkT4SLcVNuRGLs+VyuNf1+5XpkWZvy32vquO7SZOngLLBv+GIem+t3fWm0Z9s/0i1uRCQei1iUutlYjoV/LBd35H2rhob4B5phIuJin9kb0zbHf6HnaoN0CtN8r0d8G5CZiInVlG5Xcid5Byb4dddf5U2EJTDuCMVyyiM7tcnfjqw9UbVYNxtYM9SzcqIq+uVqM8pYL9xSec= diff --git a/vendor/src/github.com/RackSec/srslog/dialer.go b/vendor/src/github.com/RackSec/srslog/dialer.go index 7811538943..47a7b2beaf 100644 --- a/vendor/src/github.com/RackSec/srslog/dialer.go +++ b/vendor/src/github.com/RackSec/srslog/dialer.go @@ -5,19 +5,49 @@ import ( "net" ) -func (w Writer) getDialer() func() (serverConn, string, error) { - dialers := map[string]func() (serverConn, string, error){ - "": w.unixDialer, - "tcp+tls": w.tlsDialer, +// dialerFunctionWrapper is a simple object that consists of a dialer function +// and its name. This is primarily for testing, so we can make sure that the +// getDialer method returns the correct dialer function. However, if you ever +// find that you need to check which dialer function you have, this would also +// be useful for you without having to use reflection. +type dialerFunctionWrapper struct { + Name string + Dialer func() (serverConn, string, error) +} + +// Call the wrapped dialer function and return its return values. +func (df dialerFunctionWrapper) Call() (serverConn, string, error) { + return df.Dialer() +} + +// getDialer returns a "dialer" function that can be called to connect to a +// syslog server. +// +// Each dialer function is responsible for dialing the remote host and returns +// a serverConn, the hostname (or a default if the Writer has not specified a +// hostname), and an error in case dialing fails. +// +// The reason for separate dialers is that different network types may need +// to dial their connection differently, yet still provide a net.Conn interface +// that you can use once they have dialed. Rather than an increasingly long +// conditional, we have a map of network -> dialer function (with a sane default +// value), and adding a new network type is as easy as writing the dialer +// function and adding it to the map. +func (w *Writer) getDialer() dialerFunctionWrapper { + dialers := map[string]dialerFunctionWrapper{ + "": dialerFunctionWrapper{"unixDialer", w.unixDialer}, + "tcp+tls": dialerFunctionWrapper{"tlsDialer", w.tlsDialer}, } dialer, ok := dialers[w.network] if !ok { - dialer = w.basicDialer + dialer = dialerFunctionWrapper{"basicDialer", w.basicDialer} } return dialer } -func (w Writer) unixDialer() (serverConn, string, error) { +// unixDialer uses the unixSyslog method to open a connection to the syslog +// daemon running on the local machine. +func (w *Writer) unixDialer() (serverConn, string, error) { sc, err := unixSyslog() hostname := w.hostname if hostname == "" { @@ -26,7 +56,9 @@ func (w Writer) unixDialer() (serverConn, string, error) { return sc, hostname, err } -func (w Writer) tlsDialer() (serverConn, string, error) { +// tlsDialer connects to TLS over TCP, and is used for the "tcp+tls" network +// type. +func (w *Writer) tlsDialer() (serverConn, string, error) { c, err := tls.Dial("tcp", w.raddr, w.tlsConfig) var sc serverConn hostname := w.hostname @@ -39,7 +71,9 @@ func (w Writer) tlsDialer() (serverConn, string, error) { return sc, hostname, err } -func (w Writer) basicDialer() (serverConn, string, error) { +// basicDialer is the most common dialer for syslog, and supports both TCP and +// UDP connections. +func (w *Writer) basicDialer() (serverConn, string, error) { c, err := net.Dial(w.network, w.raddr) var sc serverConn hostname := w.hostname diff --git a/vendor/src/github.com/RackSec/srslog/formatter.go b/vendor/src/github.com/RackSec/srslog/formatter.go new file mode 100644 index 0000000000..2a74625109 --- /dev/null +++ b/vendor/src/github.com/RackSec/srslog/formatter.go @@ -0,0 +1,48 @@ +package srslog + +import ( + "fmt" + "os" + "time" +) + +// Formatter is a type of function that takes the consituent parts of a +// syslog message and returns a formatted string. A different Formatter is +// defined for each different syslog protocol we support. +type Formatter func(p Priority, hostname, tag, content string) string + +// DefaultFormatter is the original format supported by the Go syslog package, +// and is a non-compliant amalgamation of 3164 and 5424 that is intended to +// maximize compatibility. +func DefaultFormatter(p Priority, hostname, tag, content string) string { + timestamp := time.Now().Format(time.RFC3339) + msg := fmt.Sprintf("<%d> %s %s %s[%d]: %s", + p, timestamp, hostname, tag, os.Getpid(), content) + return msg +} + +// UnixFormatter omits the hostname, because it is only used locally. +func UnixFormatter(p Priority, hostname, tag, content string) string { + timestamp := time.Now().Format(time.Stamp) + msg := fmt.Sprintf("<%d>%s %s[%d]: %s", + p, timestamp, tag, os.Getpid(), content) + return msg +} + +// RFC3164Formatter provides an RFC 3164 compliant message. +func RFC3164Formatter(p Priority, hostname, tag, content string) string { + timestamp := time.Now().Format(time.Stamp) + msg := fmt.Sprintf("<%d> %s %s %s[%d]: %s", + p, timestamp, hostname, tag, os.Getpid(), content) + return msg +} + +// RFC5424Formatter provides an RFC 5424 compliant message. +func RFC5424Formatter(p Priority, hostname, tag, content string) string { + timestamp := time.Now().Format(time.RFC3339) + pid := os.Getpid() + appName := os.Args[0] + msg := fmt.Sprintf("<%d>%d %s %s %s %d %s %s", + p, 1, timestamp, hostname, appName, pid, tag, content) + return msg +} diff --git a/vendor/src/github.com/RackSec/srslog/framer.go b/vendor/src/github.com/RackSec/srslog/framer.go new file mode 100644 index 0000000000..ab46f0de74 --- /dev/null +++ b/vendor/src/github.com/RackSec/srslog/framer.go @@ -0,0 +1,24 @@ +package srslog + +import ( + "fmt" +) + +// Framer is a type of function that takes an input string (typically an +// already-formatted syslog message) and applies "message framing" to it. We +// have different framers because different versions of the syslog protocol +// and its transport requirements define different framing behavior. +type Framer func(in string) string + +// DefaultFramer does nothing, since there is no framing to apply. This is +// the original behavior of the Go syslog package, and is also typically used +// for UDP syslog. +func DefaultFramer(in string) string { + return in +} + +// RFC5425MessageLengthFramer prepends the message length to the front of the +// provided message, as defined in RFC 5425. +func RFC5425MessageLengthFramer(in string) string { + return fmt.Sprintf("%d %s", len(in), in) +} diff --git a/vendor/src/github.com/RackSec/srslog/net_conn.go b/vendor/src/github.com/RackSec/srslog/net_conn.go index a73394c69c..75e4c3ca1c 100644 --- a/vendor/src/github.com/RackSec/srslog/net_conn.go +++ b/vendor/src/github.com/RackSec/srslog/net_conn.go @@ -1,24 +1,30 @@ package srslog import ( - "fmt" "net" - "os" - "time" ) +// netConn has an internal net.Conn and adheres to the serverConn interface, +// allowing us to send syslog messages over the network. type netConn struct { conn net.Conn } -func (n *netConn) writeString(p Priority, hostname, tag, msg string) error { - timestamp := time.Now().Format(time.RFC3339) - _, err := fmt.Fprintf(n.conn, "<%d>%s %s %s[%d]: %s", - p, timestamp, hostname, - tag, os.Getpid(), msg) +// writeString formats syslog messages using time.RFC3339 and includes the +// hostname, and sends the message to the connection. +func (n *netConn) writeString(framer Framer, formatter Formatter, p Priority, hostname, tag, msg string) error { + if framer == nil { + framer = DefaultFramer + } + if formatter == nil { + formatter = DefaultFormatter + } + formattedMessage := framer(formatter(p, hostname, tag, msg)) + _, err := n.conn.Write([]byte(formattedMessage)) return err } +// close the network connection func (n *netConn) close() error { return n.conn.Close() } diff --git a/vendor/src/github.com/RackSec/srslog/srslog.go b/vendor/src/github.com/RackSec/srslog/srslog.go index 3d03272d56..4469d720c3 100644 --- a/vendor/src/github.com/RackSec/srslog/srslog.go +++ b/vendor/src/github.com/RackSec/srslog/srslog.go @@ -8,14 +8,10 @@ import ( "os" ) -// This interface and the separate syslog_unix.go file exist for -// Solaris support as implemented by gccgo. On Solaris you can not -// simply open a TCP connection to the syslog daemon. The gccgo -// sources have a syslog_solaris.go file that implements unixSyslog to -// return a type that satisfies this interface and simply calls the C -// library syslog function. +// This interface allows us to work with both local and network connections, +// and enables Solaris support (see syslog_unix.go). type serverConn interface { - writeString(p Priority, hostname, tag, s string) error + writeString(framer Framer, formatter Formatter, p Priority, hostname, tag, s string) error close() error } @@ -39,11 +35,19 @@ func Dial(network, raddr string, priority Priority, tag string) (*Writer, error) // address raddr on the specified network. It uses certPath to load TLS certificates and configure // the secure connection. func DialWithTLSCertPath(network, raddr string, priority Priority, tag, certPath string) (*Writer, error) { - pool := x509.NewCertPool() serverCert, err := ioutil.ReadFile(certPath) if err != nil { return nil, err } + + return DialWithTLSCert(network, raddr, priority, tag, serverCert) +} + +// DialWIthTLSCert establishes a secure connection to a log daemon by connecting to +// address raddr on the specified network. It uses serverCert to load a TLS certificate +// and configure the secure connection. +func DialWithTLSCert(network, raddr string, priority Priority, tag string, serverCert []byte) (*Writer, error) { + pool := x509.NewCertPool() pool.AppendCertsFromPEM(serverCert) config := tls.Config{ RootCAs: pool, diff --git a/vendor/src/github.com/RackSec/srslog/srslog_unix.go b/vendor/src/github.com/RackSec/srslog/srslog_unix.go index 430065c738..a04d9396f6 100644 --- a/vendor/src/github.com/RackSec/srslog/srslog_unix.go +++ b/vendor/src/github.com/RackSec/srslog/srslog_unix.go @@ -2,15 +2,17 @@ package srslog import ( "errors" - "fmt" + "io" "net" - "os" - "time" ) // unixSyslog opens a connection to the syslog daemon running on the -// local machine using a Unix domain socket. - +// local machine using a Unix domain socket. This function exists because of +// Solaris support as implemented by gccgo. On Solaris you can not +// simply open a TCP connection to the syslog daemon. The gccgo +// sources have a syslog_solaris.go file that implements unixSyslog to +// return a type that satisfies the serverConn interface and simply calls the C +// library syslog function. func unixSyslog() (conn serverConn, err error) { logTypes := []string{"unixgram", "unix"} logPaths := []string{"/dev/log", "/var/run/syslog", "/var/run/log"} @@ -27,21 +29,26 @@ func unixSyslog() (conn serverConn, err error) { return nil, errors.New("Unix syslog delivery error") } +// localConn adheres to the serverConn interface, allowing us to send syslog +// messages to the local syslog daemon over a Unix domain socket. type localConn struct { - conn net.Conn + conn io.WriteCloser } -func (n *localConn) writeString(p Priority, hostname, tag, msg string) error { - // Compared to the network form at srslog.netConn, the changes are: - // 1. Use time.Stamp instead of time.RFC3339. - // 2. Drop the hostname field from the Fprintf. - timestamp := time.Now().Format(time.Stamp) - _, err := fmt.Fprintf(n.conn, "<%d>%s %s[%d]: %s", - p, timestamp, - tag, os.Getpid(), msg) +// writeString formats syslog messages using time.Stamp instead of time.RFC3339, +// and omits the hostname (because it is expected to be used locally). +func (n *localConn) writeString(framer Framer, formatter Formatter, p Priority, hostname, tag, msg string) error { + if framer == nil { + framer = DefaultFramer + } + if formatter == nil { + formatter = UnixFormatter + } + _, err := n.conn.Write([]byte(framer(formatter(p, hostname, tag, msg)))) return err } +// close the (local) network connection func (n *localConn) close() error { return n.conn.Close() } diff --git a/vendor/src/github.com/RackSec/srslog/writer.go b/vendor/src/github.com/RackSec/srslog/writer.go index 1e7e2ebbdb..fdecaf61f6 100644 --- a/vendor/src/github.com/RackSec/srslog/writer.go +++ b/vendor/src/github.com/RackSec/srslog/writer.go @@ -16,6 +16,8 @@ type Writer struct { network string raddr string tlsConfig *tls.Config + framer Framer + formatter Formatter conn serverConn } @@ -32,7 +34,7 @@ func (w *Writer) connect() (err error) { var conn serverConn var hostname string dialer := w.getDialer() - conn, hostname, err = dialer() + conn, hostname, err = dialer.Call() if err == nil { w.conn = conn w.hostname = hostname @@ -41,6 +43,16 @@ func (w *Writer) connect() (err error) { return } +// SetFormatter changes the formatter function for subsequent messages. +func (w *Writer) SetFormatter(f Formatter) { + w.formatter = f +} + +// SetFramer changes the framer function for subsequent messages. +func (w *Writer) SetFramer(f Framer) { + w.framer = f +} + // Write sends a log message to the syslog daemon using the default priority // passed into `srslog.New` or the `srslog.Dial*` functions. func (w *Writer) Write(b []byte) (int, error) { @@ -133,15 +145,15 @@ func (w *Writer) writeAndRetry(p Priority, s string) (int, error) { return w.write(pr, s) } -// write generates and writes a syslog formatted string. The -// format is as follows: TIMESTAMP HOSTNAME TAG[PID]: MSG +// write generates and writes a syslog formatted string. It formats the +// message based on the current Formatter and Framer. func (w *Writer) write(p Priority, msg string) (int, error) { // ensure it ends in a \n if !strings.HasSuffix(msg, "\n") { msg += "\n" } - err := w.conn.writeString(p, w.hostname, w.tag, msg) + err := w.conn.writeString(w.framer, w.formatter, p, w.hostname, w.tag, msg) if err != nil { return 0, err }