Browse Source

Merge pull request #9841 from gyuho/vvv

vendor: upgrade dependencies except grpc-go
Gyuho Lee 7 years ago
parent
commit
587b264c79
100 changed files with 2835 additions and 2393 deletions
  1. 44 23
      Gopkg.lock
  2. 2 2
      bill-of-materials.json
  3. 29 5
      vendor/github.com/beorn7/perks/quantile/stream.go
  4. 1 0
      vendor/github.com/dgrijalva/jwt-go/ecdsa.go
  5. 1 5
      vendor/github.com/dgrijalva/jwt-go/errors.go
  6. 2 1
      vendor/github.com/dgrijalva/jwt-go/hmac.go
  7. 78 58
      vendor/github.com/dgrijalva/jwt-go/parser.go
  8. 3 2
      vendor/github.com/dgrijalva/jwt-go/rsa.go
  9. 32 0
      vendor/github.com/dgrijalva/jwt-go/rsa_utils.go
  10. 18 13
      vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_metrics.go
  11. 41 0
      vendor/github.com/grpc-ecosystem/go-grpc-prometheus/metric_options.go
  12. 17 40
      vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_metrics.go
  13. 3 3
      vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go
  14. 27 44
      vendor/github.com/prometheus/client_golang/prometheus/counter.go
  15. 26 10
      vendor/github.com/prometheus/client_golang/prometheus/desc.go
  16. 32 37
      vendor/github.com/prometheus/client_golang/prometheus/doc.go
  17. 18 51
      vendor/github.com/prometheus/client_golang/prometheus/gauge.go
  18. 15 36
      vendor/github.com/prometheus/client_golang/prometheus/go_collector.go
  19. 22 51
      vendor/github.com/prometheus/client_golang/prometheus/histogram.go
  20. 38 72
      vendor/github.com/prometheus/client_golang/prometheus/http.go
  21. 0 57
      vendor/github.com/prometheus/client_golang/prometheus/labels.go
  22. 0 50
      vendor/github.com/prometheus/client_golang/prometheus/observer.go
  23. 53 51
      vendor/github.com/prometheus/client_golang/prometheus/process_collector.go
  24. 0 199
      vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go
  25. 0 181
      vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_8.go
  26. 0 44
      vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_pre_1_8.go
  27. 14 17
      vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
  28. 0 98
      vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
  29. 0 144
      vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client_1_8.go
  30. 0 440
      vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
  31. 56 12
      vendor/github.com/prometheus/client_golang/prometheus/registry.go
  32. 29 72
      vendor/github.com/prometheus/client_golang/prometheus/summary.go
  33. 0 51
      vendor/github.com/prometheus/client_golang/prometheus/timer.go
  34. 99 3
      vendor/github.com/prometheus/client_golang/prometheus/untyped.go
  35. 6 8
      vendor/github.com/prometheus/client_golang/prometheus/value.go
  36. 92 51
      vendor/github.com/prometheus/client_golang/prometheus/vec.go
  37. 2 2
      vendor/github.com/prometheus/common/expfmt/decode.go
  38. 1 1
      vendor/github.com/prometheus/common/expfmt/expfmt.go
  39. 2 2
      vendor/github.com/prometheus/common/expfmt/text_parse.go
  40. 2 2
      vendor/github.com/prometheus/common/model/silence.go
  41. 3 0
      vendor/github.com/prometheus/common/model/time.go
  42. 2 2
      vendor/github.com/prometheus/common/model/value.go
  43. 1 1
      vendor/github.com/prometheus/procfs/buddyinfo.go
  44. 36 0
      vendor/github.com/prometheus/procfs/fs.go
  45. 46 0
      vendor/github.com/prometheus/procfs/internal/util/parse.go
  46. 18 5
      vendor/github.com/prometheus/procfs/ipvs.go
  47. 13 0
      vendor/github.com/prometheus/procfs/mdstat.go
  48. 13 0
      vendor/github.com/prometheus/procfs/mountstats.go
  49. 216 0
      vendor/github.com/prometheus/procfs/net_dev.go
  50. 263 0
      vendor/github.com/prometheus/procfs/nfs/nfs.go
  51. 317 0
      vendor/github.com/prometheus/procfs/nfs/parse.go
  52. 67 0
      vendor/github.com/prometheus/procfs/nfs/parse_nfs.go
  53. 89 0
      vendor/github.com/prometheus/procfs/nfs/parse_nfsd.go
  54. 15 1
      vendor/github.com/prometheus/procfs/proc.go
  55. 14 4
      vendor/github.com/prometheus/procfs/proc_io.go
  56. 13 0
      vendor/github.com/prometheus/procfs/proc_limits.go
  57. 68 0
      vendor/github.com/prometheus/procfs/proc_ns.go
  58. 13 0
      vendor/github.com/prometheus/procfs/proc_stat.go
  59. 13 0
      vendor/github.com/prometheus/procfs/stat.go
  60. 4 33
      vendor/github.com/prometheus/procfs/xfs/parse.go
  61. 29 17
      vendor/github.com/sirupsen/logrus/entry.go
  62. 6 0
      vendor/github.com/sirupsen/logrus/logger.go
  63. 1 1
      vendor/github.com/sirupsen/logrus/terminal_bsd.go
  64. 11 0
      vendor/github.com/sirupsen/logrus/terminal_check_appengine.go
  65. 19 0
      vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go
  66. 1 1
      vendor/github.com/sirupsen/logrus/terminal_linux.go
  67. 1 14
      vendor/github.com/sirupsen/logrus/text_formatter.go
  68. 29 0
      vendor/github.com/spf13/cobra/bash_completions.go
  69. 8 4
      vendor/github.com/spf13/pflag/flag.go
  70. 42 0
      vendor/go.uber.org/atomic/atomic.go
  71. 2 2
      vendor/golang.org/x/crypto/bcrypt/bcrypt.go
  72. 5 3
      vendor/golang.org/x/crypto/ssh/certs.go
  73. 71 71
      vendor/golang.org/x/crypto/ssh/channel.go
  74. 194 53
      vendor/golang.org/x/crypto/ssh/cipher.go
  75. 23 2
      vendor/golang.org/x/crypto/ssh/client.go
  76. 80 41
      vendor/golang.org/x/crypto/ssh/client_auth.go
  77. 15 5
      vendor/golang.org/x/crypto/ssh/common.go
  78. 6 0
      vendor/golang.org/x/crypto/ssh/handshake.go
  79. 12 12
      vendor/golang.org/x/crypto/ssh/kex.go
  80. 24 23
      vendor/golang.org/x/crypto/ssh/keys.go
  81. 23 15
      vendor/golang.org/x/crypto/ssh/messages.go
  82. 3 3
      vendor/golang.org/x/crypto/ssh/mux.go
  83. 36 6
      vendor/golang.org/x/crypto/ssh/server.go
  84. 1 1
      vendor/golang.org/x/crypto/ssh/session.go
  85. 1 0
      vendor/golang.org/x/crypto/ssh/streamlocal.go
  86. 9 0
      vendor/golang.org/x/crypto/ssh/tcpip.go
  87. 1 1
      vendor/golang.org/x/crypto/ssh/terminal/terminal.go
  88. 31 40
      vendor/golang.org/x/crypto/ssh/terminal/util.go
  89. 18 22
      vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go
  90. 12 11
      vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
  91. 24 46
      vendor/golang.org/x/crypto/ssh/transport.go
  92. 2 0
      vendor/golang.org/x/net/context/context.go
  93. 50 0
      vendor/golang.org/x/net/http/httpguts/guts.go
  94. 1 6
      vendor/golang.org/x/net/http/httpguts/httplex.go
  95. 1 1
      vendor/golang.org/x/net/http2/ciphers.go
  96. 1 1
      vendor/golang.org/x/net/http2/configure_transport.go
  97. 2 2
      vendor/golang.org/x/net/http2/frame.go
  98. 1 1
      vendor/golang.org/x/net/http2/hpack/encode.go
  99. 6 0
      vendor/golang.org/x/net/http2/hpack/hpack.go
  100. 4 4
      vendor/golang.org/x/net/http2/http2.go

+ 44 - 23
Gopkg.lock

@@ -2,9 +2,10 @@
 
 
 
 
 [[projects]]
 [[projects]]
+  branch = "master"
   name = "github.com/beorn7/perks"
   name = "github.com/beorn7/perks"
   packages = ["quantile"]
   packages = ["quantile"]
-  revision = "4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9"
+  revision = "3a771d992973f24aa725d07868b467d1ddfceafb"
 
 
 [[projects]]
 [[projects]]
   name = "github.com/bgentry/speakeasy"
   name = "github.com/bgentry/speakeasy"
@@ -46,8 +47,8 @@
 [[projects]]
 [[projects]]
   name = "github.com/dgrijalva/jwt-go"
   name = "github.com/dgrijalva/jwt-go"
   packages = ["."]
   packages = ["."]
-  revision = "d2709f9f1f31ebcda9651b03077758c1f3a0018c"
-  version = "v3.0.0"
+  revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e"
+  version = "v3.2.0"
 
 
 [[projects]]
 [[projects]]
   name = "github.com/dustin/go-humanize"
   name = "github.com/dustin/go-humanize"
@@ -102,7 +103,8 @@
 [[projects]]
 [[projects]]
   name = "github.com/grpc-ecosystem/go-grpc-prometheus"
   name = "github.com/grpc-ecosystem/go-grpc-prometheus"
   packages = ["."]
   packages = ["."]
-  revision = "0dafe0d496ea71181bf2dd039e7e3f44b6bd11a7"
+  revision = "c225b8c3b01faf2899099b768856a9e916e5087b"
+  version = "v1.2.0"
 
 
 [[projects]]
 [[projects]]
   name = "github.com/grpc-ecosystem/grpc-gateway"
   name = "github.com/grpc-ecosystem/grpc-gateway"
@@ -161,7 +163,8 @@
     "prometheus",
     "prometheus",
     "prometheus/promhttp"
     "prometheus/promhttp"
   ]
   ]
-  revision = "5cec1d0429b02e4323e042eb04dafdb079ddf568"
+  revision = "c5b7fccd204277076155f10851dad72b76a49317"
+  version = "v0.8.0"
 
 
 [[projects]]
 [[projects]]
   name = "github.com/prometheus/client_model"
   name = "github.com/prometheus/client_model"
@@ -169,27 +172,31 @@
   revision = "6f3806018612930941127f2a7c6c453ba2c527d2"
   revision = "6f3806018612930941127f2a7c6c453ba2c527d2"
 
 
 [[projects]]
 [[projects]]
+  branch = "master"
   name = "github.com/prometheus/common"
   name = "github.com/prometheus/common"
   packages = [
   packages = [
     "expfmt",
     "expfmt",
     "internal/bitbucket.org/ww/goautoneg",
     "internal/bitbucket.org/ww/goautoneg",
     "model"
     "model"
   ]
   ]
-  revision = "e3fb1a1acd7605367a2b378bc2e2f893c05174b7"
+  revision = "7600349dcfe1abd18d72d3a1770870d9800a7801"
 
 
 [[projects]]
 [[projects]]
+  branch = "master"
   name = "github.com/prometheus/procfs"
   name = "github.com/prometheus/procfs"
   packages = [
   packages = [
     ".",
     ".",
+    "internal/util",
+    "nfs",
     "xfs"
     "xfs"
   ]
   ]
-  revision = "a6e9df898b1336106c743392c48ee0b71f5c4efa"
+  revision = "7d6f385de8bea29190f15ba9931442a0eaef9af7"
 
 
 [[projects]]
 [[projects]]
   name = "github.com/sirupsen/logrus"
   name = "github.com/sirupsen/logrus"
   packages = ["."]
   packages = ["."]
-  revision = "f006c2ac4710855cf0f916dd6b77acf6b048dc6e"
-  version = "v1.0.3"
+  revision = "c155da19408a8799da419ed3eeb0cb5db0ad5dbc"
+  version = "v1.0.5"
 
 
 [[projects]]
 [[projects]]
   name = "github.com/soheilhy/cmux"
   name = "github.com/soheilhy/cmux"
@@ -200,12 +207,14 @@
 [[projects]]
 [[projects]]
   name = "github.com/spf13/cobra"
   name = "github.com/spf13/cobra"
   packages = ["."]
   packages = ["."]
-  revision = "cd30c2a7e91a1d63fd9a0027accf18a681e9d50b"
+  revision = "ef82de70bb3f60c65fb8eebacbb2d122ef517385"
+  version = "v0.0.3"
 
 
 [[projects]]
 [[projects]]
   name = "github.com/spf13/pflag"
   name = "github.com/spf13/pflag"
   packages = ["."]
   packages = ["."]
-  revision = "1ce0cc6db4029d97571db82f85092fccedb572ce"
+  revision = "583c0c0531f06d5278b7d917446061adc344b5cd"
+  version = "v1.0.1"
 
 
 [[projects]]
 [[projects]]
   name = "github.com/tmc/grpc-websocket-proxy"
   name = "github.com/tmc/grpc-websocket-proxy"
@@ -233,8 +242,8 @@
 [[projects]]
 [[projects]]
   name = "go.uber.org/atomic"
   name = "go.uber.org/atomic"
   packages = ["."]
   packages = ["."]
-  revision = "8474b86a5a6f79c443ce4b2992817ff32cf208b8"
-  version = "v1.3.1"
+  revision = "1ea20fb1cbb1cc08cbd0d913a96dead89aa18289"
+  version = "v1.3.2"
 
 
 [[projects]]
 [[projects]]
   name = "go.uber.org/multierr"
   name = "go.uber.org/multierr"
@@ -256,41 +265,49 @@
   version = "v1.8.0"
   version = "v1.8.0"
 
 
 [[projects]]
 [[projects]]
+  branch = "master"
   name = "golang.org/x/crypto"
   name = "golang.org/x/crypto"
   packages = [
   packages = [
     "bcrypt",
     "bcrypt",
     "blowfish",
     "blowfish",
     "ssh/terminal"
     "ssh/terminal"
   ]
   ]
-  revision = "9419663f5a44be8b34ca85f08abc5fe1be11f8a3"
+  revision = "8ac0e0d97ce45cd83d1d7243c060cb8461dda5e9"
 
 
 [[projects]]
 [[projects]]
+  branch = "master"
   name = "golang.org/x/net"
   name = "golang.org/x/net"
   packages = [
   packages = [
     "context",
     "context",
+    "http/httpguts",
     "http2",
     "http2",
     "http2/hpack",
     "http2/hpack",
     "idna",
     "idna",
     "internal/timeseries",
     "internal/timeseries",
-    "lex/httplex",
     "trace"
     "trace"
   ]
   ]
-  revision = "66aacef3dd8a676686c7ae3716979581e8b03c47"
+  revision = "db08ff08e8622530d9ed3a0e8ac279f6d4c02196"
 
 
 [[projects]]
 [[projects]]
+  branch = "master"
   name = "golang.org/x/sys"
   name = "golang.org/x/sys"
   packages = [
   packages = [
     "unix",
     "unix",
     "windows"
     "windows"
   ]
   ]
-  revision = "ebfc5b4631820b793c9010c87fd8fef0f39eb082"
+  revision = "56ede360ec1c541828fb88741b3f1049406d28f5"
 
 
 [[projects]]
 [[projects]]
   name = "golang.org/x/text"
   name = "golang.org/x/text"
   packages = [
   packages = [
+    "collate",
+    "collate/build",
+    "internal/colltab",
     "internal/gen",
     "internal/gen",
+    "internal/tag",
     "internal/triegen",
     "internal/triegen",
     "internal/ucd",
     "internal/ucd",
+    "language",
     "secure/bidirule",
     "secure/bidirule",
     "transform",
     "transform",
     "unicode/bidi",
     "unicode/bidi",
@@ -298,17 +315,20 @@
     "unicode/norm",
     "unicode/norm",
     "unicode/rangetable"
     "unicode/rangetable"
   ]
   ]
-  revision = "b19bf474d317b857955b12035d2c5acb57ce8b01"
+  revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
+  version = "v0.3.0"
 
 
 [[projects]]
 [[projects]]
+  branch = "master"
   name = "golang.org/x/time"
   name = "golang.org/x/time"
   packages = ["rate"]
   packages = ["rate"]
-  revision = "c06e80d9300e4443158a03817b8a8cb37d230320"
+  revision = "fbb02b2291d28baffd63558aa44b4b56f178d650"
 
 
 [[projects]]
 [[projects]]
+  branch = "master"
   name = "google.golang.org/genproto"
   name = "google.golang.org/genproto"
   packages = ["googleapis/rpc/status"]
   packages = ["googleapis/rpc/status"]
-  revision = "09f6ed296fc66555a25fe4ce95173148778dfa85"
+  revision = "32ee49c4dd805befd833990acba36cb75042378c"
 
 
 [[projects]]
 [[projects]]
   name = "google.golang.org/grpc"
   name = "google.golang.org/grpc"
@@ -339,13 +359,14 @@
 [[projects]]
 [[projects]]
   name = "gopkg.in/cheggaaa/pb.v1"
   name = "gopkg.in/cheggaaa/pb.v1"
   packages = ["."]
   packages = ["."]
-  revision = "226d21d43a305fac52b3a104ef83e721b15275e0"
-  version = "v1.0.2"
+  revision = "2af8bbdea9e99e83b3ac400d8f6b6d1b8cbbf338"
+  version = "v1.0.25"
 
 
 [[projects]]
 [[projects]]
   name = "gopkg.in/yaml.v2"
   name = "gopkg.in/yaml.v2"
   packages = ["."]
   packages = ["."]
-  revision = "cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b"
+  revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
+  version = "v2.2.1"
 
 
 [solve-meta]
 [solve-meta]
   analyzer-name = "dep"
   analyzer-name = "dep"

+ 2 - 2
bill-of-materials.json

@@ -408,8 +408,8 @@
 		"project": "gopkg.in/yaml.v2",
 		"project": "gopkg.in/yaml.v2",
 		"licenses": [
 		"licenses": [
 			{
 			{
-				"type": "The Unlicense",
-				"confidence": 0.35294117647058826
+				"type": "Apache License 2.0",
+				"confidence": 1
 			},
 			},
 			{
 			{
 				"type": "MIT License",
 				"type": "MIT License",

+ 29 - 5
vendor/github.com/beorn7/perks/quantile/stream.go

@@ -77,15 +77,20 @@ func NewHighBiased(epsilon float64) *Stream {
 // is guaranteed to be within (Quantile±Epsilon).
 // is guaranteed to be within (Quantile±Epsilon).
 //
 //
 // See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error properties.
 // See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error properties.
-func NewTargeted(targets map[float64]float64) *Stream {
+func NewTargeted(targetMap map[float64]float64) *Stream {
+	// Convert map to slice to avoid slow iterations on a map.
+	// ƒ is called on the hot path, so converting the map to a slice
+	// beforehand results in significant CPU savings.
+	targets := targetMapToSlice(targetMap)
+
 	ƒ := func(s *stream, r float64) float64 {
 	ƒ := func(s *stream, r float64) float64 {
 		var m = math.MaxFloat64
 		var m = math.MaxFloat64
 		var f float64
 		var f float64
-		for quantile, epsilon := range targets {
-			if quantile*s.n <= r {
-				f = (2 * epsilon * r) / quantile
+		for _, t := range targets {
+			if t.quantile*s.n <= r {
+				f = (2 * t.epsilon * r) / t.quantile
 			} else {
 			} else {
-				f = (2 * epsilon * (s.n - r)) / (1 - quantile)
+				f = (2 * t.epsilon * (s.n - r)) / (1 - t.quantile)
 			}
 			}
 			if f < m {
 			if f < m {
 				m = f
 				m = f
@@ -96,6 +101,25 @@ func NewTargeted(targets map[float64]float64) *Stream {
 	return newStream(ƒ)
 	return newStream(ƒ)
 }
 }
 
 
+type target struct {
+	quantile float64
+	epsilon  float64
+}
+
+func targetMapToSlice(targetMap map[float64]float64) []target {
+	targets := make([]target, 0, len(targetMap))
+
+	for quantile, epsilon := range targetMap {
+		t := target{
+			quantile: quantile,
+			epsilon:  epsilon,
+		}
+		targets = append(targets, t)
+	}
+
+	return targets
+}
+
 // Stream computes quantiles for a stream of float64s. It is not thread-safe by
 // Stream computes quantiles for a stream of float64s. It is not thread-safe by
 // design. Take care when using across multiple goroutines.
 // design. Take care when using across multiple goroutines.
 type Stream struct {
 type Stream struct {

+ 1 - 0
vendor/github.com/dgrijalva/jwt-go/ecdsa.go

@@ -14,6 +14,7 @@ var (
 )
 )
 
 
 // Implements the ECDSA family of signing methods signing methods
 // Implements the ECDSA family of signing methods signing methods
+// Expects *ecdsa.PrivateKey for signing and *ecdsa.PublicKey for verification
 type SigningMethodECDSA struct {
 type SigningMethodECDSA struct {
 	Name      string
 	Name      string
 	Hash      crypto.Hash
 	Hash      crypto.Hash

+ 1 - 5
vendor/github.com/dgrijalva/jwt-go/errors.go

@@ -51,13 +51,9 @@ func (e ValidationError) Error() string {
 	} else {
 	} else {
 		return "token is invalid"
 		return "token is invalid"
 	}
 	}
-	return e.Inner.Error()
 }
 }
 
 
 // No errors
 // No errors
 func (e *ValidationError) valid() bool {
 func (e *ValidationError) valid() bool {
-	if e.Errors > 0 {
-		return false
-	}
-	return true
+	return e.Errors == 0
 }
 }

+ 2 - 1
vendor/github.com/dgrijalva/jwt-go/hmac.go

@@ -7,6 +7,7 @@ import (
 )
 )
 
 
 // Implements the HMAC-SHA family of signing methods signing methods
 // Implements the HMAC-SHA family of signing methods signing methods
+// Expects key type of []byte for both signing and validation
 type SigningMethodHMAC struct {
 type SigningMethodHMAC struct {
 	Name string
 	Name string
 	Hash crypto.Hash
 	Hash crypto.Hash
@@ -90,5 +91,5 @@ func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) (string,
 		return EncodeSegment(hasher.Sum(nil)), nil
 		return EncodeSegment(hasher.Sum(nil)), nil
 	}
 	}
 
 
-	return "", ErrInvalidKey
+	return "", ErrInvalidKeyType
 }
 }

+ 78 - 58
vendor/github.com/dgrijalva/jwt-go/parser.go

@@ -8,8 +8,9 @@ import (
 )
 )
 
 
 type Parser struct {
 type Parser struct {
-	ValidMethods  []string // If populated, only these methods will be considered valid
-	UseJSONNumber bool     // Use JSON Number format in JSON decoder
+	ValidMethods         []string // If populated, only these methods will be considered valid
+	UseJSONNumber        bool     // Use JSON Number format in JSON decoder
+	SkipClaimsValidation bool     // Skip claims validation during token parsing
 }
 }
 
 
 // Parse, validate, and return a token.
 // Parse, validate, and return a token.
@@ -20,55 +21,9 @@ func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
 }
 }
 
 
 func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {
 func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {
-	parts := strings.Split(tokenString, ".")
-	if len(parts) != 3 {
-		return nil, NewValidationError("token contains an invalid number of segments", ValidationErrorMalformed)
-	}
-
-	var err error
-	token := &Token{Raw: tokenString}
-
-	// parse Header
-	var headerBytes []byte
-	if headerBytes, err = DecodeSegment(parts[0]); err != nil {
-		if strings.HasPrefix(strings.ToLower(tokenString), "bearer ") {
-			return token, NewValidationError("tokenstring should not contain 'bearer '", ValidationErrorMalformed)
-		}
-		return token, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}
-	}
-	if err = json.Unmarshal(headerBytes, &token.Header); err != nil {
-		return token, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}
-	}
-
-	// parse Claims
-	var claimBytes []byte
-	token.Claims = claims
-
-	if claimBytes, err = DecodeSegment(parts[1]); err != nil {
-		return token, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}
-	}
-	dec := json.NewDecoder(bytes.NewBuffer(claimBytes))
-	if p.UseJSONNumber {
-		dec.UseNumber()
-	}
-	// JSON Decode.  Special case for map type to avoid weird pointer behavior
-	if c, ok := token.Claims.(MapClaims); ok {
-		err = dec.Decode(&c)
-	} else {
-		err = dec.Decode(&claims)
-	}
-	// Handle decode error
+	token, parts, err := p.ParseUnverified(tokenString, claims)
 	if err != nil {
 	if err != nil {
-		return token, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}
-	}
-
-	// Lookup signature method
-	if method, ok := token.Header["alg"].(string); ok {
-		if token.Method = GetSigningMethod(method); token.Method == nil {
-			return token, NewValidationError("signing method (alg) is unavailable.", ValidationErrorUnverifiable)
-		}
-	} else {
-		return token, NewValidationError("signing method (alg) is unspecified.", ValidationErrorUnverifiable)
+		return token, err
 	}
 	}
 
 
 	// Verify signing method is in the required set
 	// Verify signing method is in the required set
@@ -95,20 +50,25 @@ func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyf
 	}
 	}
 	if key, err = keyFunc(token); err != nil {
 	if key, err = keyFunc(token); err != nil {
 		// keyFunc returned an error
 		// keyFunc returned an error
+		if ve, ok := err.(*ValidationError); ok {
+			return token, ve
+		}
 		return token, &ValidationError{Inner: err, Errors: ValidationErrorUnverifiable}
 		return token, &ValidationError{Inner: err, Errors: ValidationErrorUnverifiable}
 	}
 	}
 
 
 	vErr := &ValidationError{}
 	vErr := &ValidationError{}
 
 
 	// Validate Claims
 	// Validate Claims
-	if err := token.Claims.Valid(); err != nil {
-
-		// If the Claims Valid returned an error, check if it is a validation error,
-		// If it was another error type, create a ValidationError with a generic ClaimsInvalid flag set
-		if e, ok := err.(*ValidationError); !ok {
-			vErr = &ValidationError{Inner: err, Errors: ValidationErrorClaimsInvalid}
-		} else {
-			vErr = e
+	if !p.SkipClaimsValidation {
+		if err := token.Claims.Valid(); err != nil {
+
+			// If the Claims Valid returned an error, check if it is a validation error,
+			// If it was another error type, create a ValidationError with a generic ClaimsInvalid flag set
+			if e, ok := err.(*ValidationError); !ok {
+				vErr = &ValidationError{Inner: err, Errors: ValidationErrorClaimsInvalid}
+			} else {
+				vErr = e
+			}
 		}
 		}
 	}
 	}
 
 
@@ -126,3 +86,63 @@ func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyf
 
 
 	return token, vErr
 	return token, vErr
 }
 }
+
+// WARNING: Don't use this method unless you know what you're doing
+//
+// This method parses the token but doesn't validate the signature. It's only
+// ever useful in cases where you know the signature is valid (because it has
+// been checked previously in the stack) and you want to extract values from
+// it.
+func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Token, parts []string, err error) {
+	parts = strings.Split(tokenString, ".")
+	if len(parts) != 3 {
+		return nil, parts, NewValidationError("token contains an invalid number of segments", ValidationErrorMalformed)
+	}
+
+	token = &Token{Raw: tokenString}
+
+	// parse Header
+	var headerBytes []byte
+	if headerBytes, err = DecodeSegment(parts[0]); err != nil {
+		if strings.HasPrefix(strings.ToLower(tokenString), "bearer ") {
+			return token, parts, NewValidationError("tokenstring should not contain 'bearer '", ValidationErrorMalformed)
+		}
+		return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}
+	}
+	if err = json.Unmarshal(headerBytes, &token.Header); err != nil {
+		return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}
+	}
+
+	// parse Claims
+	var claimBytes []byte
+	token.Claims = claims
+
+	if claimBytes, err = DecodeSegment(parts[1]); err != nil {
+		return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}
+	}
+	dec := json.NewDecoder(bytes.NewBuffer(claimBytes))
+	if p.UseJSONNumber {
+		dec.UseNumber()
+	}
+	// JSON Decode.  Special case for map type to avoid weird pointer behavior
+	if c, ok := token.Claims.(MapClaims); ok {
+		err = dec.Decode(&c)
+	} else {
+		err = dec.Decode(&claims)
+	}
+	// Handle decode error
+	if err != nil {
+		return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed}
+	}
+
+	// Lookup signature method
+	if method, ok := token.Header["alg"].(string); ok {
+		if token.Method = GetSigningMethod(method); token.Method == nil {
+			return token, parts, NewValidationError("signing method (alg) is unavailable.", ValidationErrorUnverifiable)
+		}
+	} else {
+		return token, parts, NewValidationError("signing method (alg) is unspecified.", ValidationErrorUnverifiable)
+	}
+
+	return token, parts, nil
+}

+ 3 - 2
vendor/github.com/dgrijalva/jwt-go/rsa.go

@@ -7,6 +7,7 @@ import (
 )
 )
 
 
 // Implements the RSA family of signing methods signing methods
 // Implements the RSA family of signing methods signing methods
+// Expects *rsa.PrivateKey for signing and *rsa.PublicKey for validation
 type SigningMethodRSA struct {
 type SigningMethodRSA struct {
 	Name string
 	Name string
 	Hash crypto.Hash
 	Hash crypto.Hash
@@ -44,7 +45,7 @@ func (m *SigningMethodRSA) Alg() string {
 }
 }
 
 
 // Implements the Verify method from SigningMethod
 // Implements the Verify method from SigningMethod
-// For this signing method, must be an rsa.PublicKey structure.
+// For this signing method, must be an *rsa.PublicKey structure.
 func (m *SigningMethodRSA) Verify(signingString, signature string, key interface{}) error {
 func (m *SigningMethodRSA) Verify(signingString, signature string, key interface{}) error {
 	var err error
 	var err error
 
 
@@ -73,7 +74,7 @@ func (m *SigningMethodRSA) Verify(signingString, signature string, key interface
 }
 }
 
 
 // Implements the Sign method from SigningMethod
 // Implements the Sign method from SigningMethod
-// For this signing method, must be an rsa.PrivateKey structure.
+// For this signing method, must be an *rsa.PrivateKey structure.
 func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string, error) {
 func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string, error) {
 	var rsaKey *rsa.PrivateKey
 	var rsaKey *rsa.PrivateKey
 	var ok bool
 	var ok bool

+ 32 - 0
vendor/github.com/dgrijalva/jwt-go/rsa_utils.go

@@ -39,6 +39,38 @@ func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) {
 	return pkey, nil
 	return pkey, nil
 }
 }
 
 
+// Parse PEM encoded PKCS1 or PKCS8 private key protected with password
+func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.PrivateKey, error) {
+	var err error
+
+	// Parse PEM block
+	var block *pem.Block
+	if block, _ = pem.Decode(key); block == nil {
+		return nil, ErrKeyMustBePEMEncoded
+	}
+
+	var parsedKey interface{}
+
+	var blockDecrypted []byte
+	if blockDecrypted, err = x509.DecryptPEMBlock(block, []byte(password)); err != nil {
+		return nil, err
+	}
+
+	if parsedKey, err = x509.ParsePKCS1PrivateKey(blockDecrypted); err != nil {
+		if parsedKey, err = x509.ParsePKCS8PrivateKey(blockDecrypted); err != nil {
+			return nil, err
+		}
+	}
+
+	var pkey *rsa.PrivateKey
+	var ok bool
+	if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok {
+		return nil, ErrNotRSAPrivateKey
+	}
+
+	return pkey, nil
+}
+
 // Parse PEM encoded PKCS1 or PKCS8 public key
 // Parse PEM encoded PKCS1 or PKCS8 public key
 func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) {
 func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) {
 	var err error
 	var err error

+ 18 - 13
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/client_metrics.go

@@ -7,6 +7,7 @@ import (
 	"golang.org/x/net/context"
 	"golang.org/x/net/context"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
 )
 )
 
 
 // ClientMetrics represents a collection of metrics to be registered on a
 // ClientMetrics represents a collection of metrics to be registered on a
@@ -25,31 +26,32 @@ type ClientMetrics struct {
 // ClientMetrics when not using the default Prometheus metrics registry, for
 // ClientMetrics when not using the default Prometheus metrics registry, for
 // example when wanting to control which metrics are added to a registry as
 // example when wanting to control which metrics are added to a registry as
 // opposed to automatically adding metrics via init functions.
 // opposed to automatically adding metrics via init functions.
-func NewClientMetrics() *ClientMetrics {
+func NewClientMetrics(counterOpts ...CounterOption) *ClientMetrics {
+	opts := counterOptions(counterOpts)
 	return &ClientMetrics{
 	return &ClientMetrics{
 		clientStartedCounter: prom.NewCounterVec(
 		clientStartedCounter: prom.NewCounterVec(
-			prom.CounterOpts{
+			opts.apply(prom.CounterOpts{
 				Name: "grpc_client_started_total",
 				Name: "grpc_client_started_total",
 				Help: "Total number of RPCs started on the client.",
 				Help: "Total number of RPCs started on the client.",
-			}, []string{"grpc_type", "grpc_service", "grpc_method"}),
+			}), []string{"grpc_type", "grpc_service", "grpc_method"}),
 
 
 		clientHandledCounter: prom.NewCounterVec(
 		clientHandledCounter: prom.NewCounterVec(
-			prom.CounterOpts{
+			opts.apply(prom.CounterOpts{
 				Name: "grpc_client_handled_total",
 				Name: "grpc_client_handled_total",
 				Help: "Total number of RPCs completed by the client, regardless of success or failure.",
 				Help: "Total number of RPCs completed by the client, regardless of success or failure.",
-			}, []string{"grpc_type", "grpc_service", "grpc_method", "grpc_code"}),
+			}), []string{"grpc_type", "grpc_service", "grpc_method", "grpc_code"}),
 
 
 		clientStreamMsgReceived: prom.NewCounterVec(
 		clientStreamMsgReceived: prom.NewCounterVec(
-			prom.CounterOpts{
+			opts.apply(prom.CounterOpts{
 				Name: "grpc_client_msg_received_total",
 				Name: "grpc_client_msg_received_total",
 				Help: "Total number of RPC stream messages received by the client.",
 				Help: "Total number of RPC stream messages received by the client.",
-			}, []string{"grpc_type", "grpc_service", "grpc_method"}),
+			}), []string{"grpc_type", "grpc_service", "grpc_method"}),
 
 
 		clientStreamMsgSent: prom.NewCounterVec(
 		clientStreamMsgSent: prom.NewCounterVec(
-			prom.CounterOpts{
+			opts.apply(prom.CounterOpts{
 				Name: "grpc_client_msg_sent_total",
 				Name: "grpc_client_msg_sent_total",
 				Help: "Total number of gRPC stream messages sent by the client.",
 				Help: "Total number of gRPC stream messages sent by the client.",
-			}, []string{"grpc_type", "grpc_service", "grpc_method"}),
+			}), []string{"grpc_type", "grpc_service", "grpc_method"}),
 
 
 		clientHandledHistogramEnabled: false,
 		clientHandledHistogramEnabled: false,
 		clientHandledHistogramOpts: prom.HistogramOpts{
 		clientHandledHistogramOpts: prom.HistogramOpts{
@@ -111,18 +113,20 @@ func (m *ClientMetrics) UnaryClientInterceptor() func(ctx context.Context, metho
 		if err != nil {
 		if err != nil {
 			monitor.ReceivedMessage()
 			monitor.ReceivedMessage()
 		}
 		}
-		monitor.Handled(grpc.Code(err))
+		st, _ := status.FromError(err)
+		monitor.Handled(st.Code())
 		return err
 		return err
 	}
 	}
 }
 }
 
 
-// StreamServerInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Streaming RPCs.
+// StreamClientInterceptor is a gRPC client-side interceptor that provides Prometheus monitoring for Streaming RPCs.
 func (m *ClientMetrics) StreamClientInterceptor() func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
 func (m *ClientMetrics) StreamClientInterceptor() func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
 	return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
 	return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
 		monitor := newClientReporter(m, clientStreamType(desc), method)
 		monitor := newClientReporter(m, clientStreamType(desc), method)
 		clientStream, err := streamer(ctx, desc, cc, method, opts...)
 		clientStream, err := streamer(ctx, desc, cc, method, opts...)
 		if err != nil {
 		if err != nil {
-			monitor.Handled(grpc.Code(err))
+			st, _ := status.FromError(err)
+			monitor.Handled(st.Code())
 			return nil, err
 			return nil, err
 		}
 		}
 		return &monitoredClientStream{clientStream, monitor}, nil
 		return &monitoredClientStream{clientStream, monitor}, nil
@@ -159,7 +163,8 @@ func (s *monitoredClientStream) RecvMsg(m interface{}) error {
 	} else if err == io.EOF {
 	} else if err == io.EOF {
 		s.monitor.Handled(codes.OK)
 		s.monitor.Handled(codes.OK)
 	} else {
 	} else {
-		s.monitor.Handled(grpc.Code(err))
+		st, _ := status.FromError(err)
+		s.monitor.Handled(st.Code())
 	}
 	}
 	return err
 	return err
 }
 }

+ 41 - 0
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/metric_options.go

@@ -0,0 +1,41 @@
+package grpc_prometheus
+
+import (
+	prom "github.com/prometheus/client_golang/prometheus"
+)
+
+// A CounterOption lets you add options to Counter metrics using With* funcs.
+type CounterOption func(*prom.CounterOpts)
+
+type counterOptions []CounterOption
+
+func (co counterOptions) apply(o prom.CounterOpts) prom.CounterOpts {
+	for _, f := range co {
+		f(&o)
+	}
+	return o
+}
+
+// WithConstLabels allows you to add ConstLabels to Counter metrics.
+func WithConstLabels(labels prom.Labels) CounterOption {
+	return func(o *prom.CounterOpts) {
+		o.ConstLabels = labels
+	}
+}
+
+// A HistogramOption lets you add options to Histogram metrics using With*
+// funcs.
+type HistogramOption func(*prom.HistogramOpts)
+
+// WithHistogramBuckets allows you to specify custom bucket ranges for histograms if EnableHandlingTimeHistogram is on.
+func WithHistogramBuckets(buckets []float64) HistogramOption {
+	return func(o *prom.HistogramOpts) { o.Buckets = buckets }
+}
+
+// WithHistogramConstLabels allows you to add custom ConstLabels to
+// histograms metrics.
+func WithHistogramConstLabels(labels prom.Labels) HistogramOption {
+	return func(o *prom.HistogramOpts) {
+		o.ConstLabels = labels
+	}
+}

+ 17 - 40
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/server_metrics.go

@@ -4,6 +4,7 @@ import (
 	prom "github.com/prometheus/client_golang/prometheus"
 	prom "github.com/prometheus/client_golang/prometheus"
 	"golang.org/x/net/context"
 	"golang.org/x/net/context"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc"
+	"google.golang.org/grpc/status"
 )
 )
 
 
 // ServerMetrics represents a collection of metrics to be registered on a
 // ServerMetrics represents a collection of metrics to be registered on a
@@ -22,28 +23,29 @@ type ServerMetrics struct {
 // ServerMetrics when not using the default Prometheus metrics registry, for
 // ServerMetrics when not using the default Prometheus metrics registry, for
 // example when wanting to control which metrics are added to a registry as
 // example when wanting to control which metrics are added to a registry as
 // opposed to automatically adding metrics via init functions.
 // opposed to automatically adding metrics via init functions.
-func NewServerMetrics() *ServerMetrics {
+func NewServerMetrics(counterOpts ...CounterOption) *ServerMetrics {
+	opts := counterOptions(counterOpts)
 	return &ServerMetrics{
 	return &ServerMetrics{
 		serverStartedCounter: prom.NewCounterVec(
 		serverStartedCounter: prom.NewCounterVec(
-			prom.CounterOpts{
+			opts.apply(prom.CounterOpts{
 				Name: "grpc_server_started_total",
 				Name: "grpc_server_started_total",
 				Help: "Total number of RPCs started on the server.",
 				Help: "Total number of RPCs started on the server.",
-			}, []string{"grpc_type", "grpc_service", "grpc_method"}),
+			}), []string{"grpc_type", "grpc_service", "grpc_method"}),
 		serverHandledCounter: prom.NewCounterVec(
 		serverHandledCounter: prom.NewCounterVec(
-			prom.CounterOpts{
+			opts.apply(prom.CounterOpts{
 				Name: "grpc_server_handled_total",
 				Name: "grpc_server_handled_total",
 				Help: "Total number of RPCs completed on the server, regardless of success or failure.",
 				Help: "Total number of RPCs completed on the server, regardless of success or failure.",
-			}, []string{"grpc_type", "grpc_service", "grpc_method", "grpc_code"}),
+			}), []string{"grpc_type", "grpc_service", "grpc_method", "grpc_code"}),
 		serverStreamMsgReceived: prom.NewCounterVec(
 		serverStreamMsgReceived: prom.NewCounterVec(
-			prom.CounterOpts{
+			opts.apply(prom.CounterOpts{
 				Name: "grpc_server_msg_received_total",
 				Name: "grpc_server_msg_received_total",
 				Help: "Total number of RPC stream messages received on the server.",
 				Help: "Total number of RPC stream messages received on the server.",
-			}, []string{"grpc_type", "grpc_service", "grpc_method"}),
+			}), []string{"grpc_type", "grpc_service", "grpc_method"}),
 		serverStreamMsgSent: prom.NewCounterVec(
 		serverStreamMsgSent: prom.NewCounterVec(
-			prom.CounterOpts{
+			opts.apply(prom.CounterOpts{
 				Name: "grpc_server_msg_sent_total",
 				Name: "grpc_server_msg_sent_total",
 				Help: "Total number of gRPC stream messages sent by the server.",
 				Help: "Total number of gRPC stream messages sent by the server.",
-			}, []string{"grpc_type", "grpc_service", "grpc_method"}),
+			}), []string{"grpc_type", "grpc_service", "grpc_method"}),
 		serverHandledHistogramEnabled: false,
 		serverHandledHistogramEnabled: false,
 		serverHandledHistogramOpts: prom.HistogramOpts{
 		serverHandledHistogramOpts: prom.HistogramOpts{
 			Name:    "grpc_server_handling_seconds",
 			Name:    "grpc_server_handling_seconds",
@@ -54,13 +56,6 @@ func NewServerMetrics() *ServerMetrics {
 	}
 	}
 }
 }
 
 
-type HistogramOption func(*prom.HistogramOpts)
-
-// WithHistogramBuckets allows you to specify custom bucket ranges for histograms if EnableHandlingTimeHistogram is on.
-func WithHistogramBuckets(buckets []float64) HistogramOption {
-	return func(o *prom.HistogramOpts) { o.Buckets = buckets }
-}
-
 // EnableHandlingTimeHistogram enables histograms being registered when
 // EnableHandlingTimeHistogram enables histograms being registered when
 // registering the ServerMetrics on a Prometheus registry. Histograms can be
 // registering the ServerMetrics on a Prometheus registry. Histograms can be
 // expensive on Prometheus servers. It takes options to configure histogram
 // expensive on Prometheus servers. It takes options to configure histogram
@@ -110,7 +105,8 @@ func (m *ServerMetrics) UnaryServerInterceptor() func(ctx context.Context, req i
 		monitor := newServerReporter(m, Unary, info.FullMethod)
 		monitor := newServerReporter(m, Unary, info.FullMethod)
 		monitor.ReceivedMessage()
 		monitor.ReceivedMessage()
 		resp, err := handler(ctx, req)
 		resp, err := handler(ctx, req)
-		monitor.Handled(grpc.Code(err))
+		st, _ := status.FromError(err)
+		monitor.Handled(st.Code())
 		if err == nil {
 		if err == nil {
 			monitor.SentMessage()
 			monitor.SentMessage()
 		}
 		}
@@ -121,9 +117,10 @@ func (m *ServerMetrics) UnaryServerInterceptor() func(ctx context.Context, req i
 // StreamServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Streaming RPCs.
 // StreamServerInterceptor is a gRPC server-side interceptor that provides Prometheus monitoring for Streaming RPCs.
 func (m *ServerMetrics) StreamServerInterceptor() func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
 func (m *ServerMetrics) StreamServerInterceptor() func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
 	return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
 	return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
-		monitor := newServerReporter(m, streamRpcType(info), info.FullMethod)
+		monitor := newServerReporter(m, streamRPCType(info), info.FullMethod)
 		err := handler(srv, &monitoredServerStream{ss, monitor})
 		err := handler(srv, &monitoredServerStream{ss, monitor})
-		monitor.Handled(grpc.Code(err))
+		st, _ := status.FromError(err)
+		monitor.Handled(st.Code())
 		return err
 		return err
 	}
 	}
 }
 }
@@ -140,27 +137,7 @@ func (m *ServerMetrics) InitializeMetrics(server *grpc.Server) {
 	}
 	}
 }
 }
 
 
-// Register registers all server metrics in a given metrics registry. Depending
-// on histogram options and whether they are enabled, histogram metrics are
-// also registered.
-//
-// Deprecated: ServerMetrics implements Prometheus Collector interface. You can
-// register an instance of ServerMetrics directly by using
-// prometheus.Register(m).
-func (m *ServerMetrics) Register(r prom.Registerer) error {
-	return r.Register(m)
-}
-
-// MustRegister tries to register all server metrics and panics on an error.
-//
-// Deprecated: ServerMetrics implements Prometheus Collector interface. You can
-// register an instance of ServerMetrics directly by using
-// prometheus.MustRegister(m).
-func (m *ServerMetrics) MustRegister(r prom.Registerer) {
-	r.MustRegister(m)
-}
-
-func streamRpcType(info *grpc.StreamServerInfo) grpcType {
+func streamRPCType(info *grpc.StreamServerInfo) grpcType {
 	if info.IsClientStream && !info.IsServerStream {
 	if info.IsClientStream && !info.IsServerStream {
 		return ClientStream
 		return ClientStream
 	} else if !info.IsClientStream && info.IsServerStream {
 	} else if !info.IsClientStream && info.IsServerStream {

+ 3 - 3
vendor/github.com/grpc-ecosystem/go-grpc-prometheus/util.go

@@ -37,13 +37,13 @@ func splitMethodName(fullMethodName string) (string, string) {
 }
 }
 
 
 func typeFromMethodInfo(mInfo *grpc.MethodInfo) grpcType {
 func typeFromMethodInfo(mInfo *grpc.MethodInfo) grpcType {
-	if mInfo.IsClientStream == false && mInfo.IsServerStream == false {
+	if !mInfo.IsClientStream && !mInfo.IsServerStream {
 		return Unary
 		return Unary
 	}
 	}
-	if mInfo.IsClientStream == true && mInfo.IsServerStream == false {
+	if mInfo.IsClientStream && !mInfo.IsServerStream {
 		return ClientStream
 		return ClientStream
 	}
 	}
-	if mInfo.IsClientStream == false && mInfo.IsServerStream == true {
+	if !mInfo.IsClientStream && mInfo.IsServerStream {
 		return ServerStream
 		return ServerStream
 	}
 	}
 	return BidiStream
 	return BidiStream

+ 27 - 44
vendor/github.com/prometheus/client_golang/prometheus/counter.go

@@ -30,8 +30,16 @@ type Counter interface {
 	Metric
 	Metric
 	Collector
 	Collector
 
 
-	// Inc increments the counter by 1. Use Add to increment it by arbitrary
-	// non-negative values.
+	// Set is used to set the Counter to an arbitrary value. It is only used
+	// if you have to transfer a value from an external counter into this
+	// Prometheus metric. Do not use it for regular handling of a
+	// Prometheus counter (as it can be used to break the contract of
+	// monotonically increasing values).
+	//
+	// Deprecated: Use NewConstMetric to create a counter for an external
+	// value. A Counter should never be set.
+	Set(float64)
+	// Inc increments the counter by 1.
 	Inc()
 	Inc()
 	// Add adds the given value to the counter. It panics if the value is <
 	// Add adds the given value to the counter. It panics if the value is <
 	// 0.
 	// 0.
@@ -70,12 +78,16 @@ func (c *counter) Add(v float64) {
 // if you want to count the same thing partitioned by various dimensions
 // if you want to count the same thing partitioned by various dimensions
 // (e.g. number of HTTP requests, partitioned by response code and
 // (e.g. number of HTTP requests, partitioned by response code and
 // method). Create instances with NewCounterVec.
 // method). Create instances with NewCounterVec.
+//
+// CounterVec embeds MetricVec. See there for a full list of methods with
+// detailed documentation.
 type CounterVec struct {
 type CounterVec struct {
-	*metricVec
+	*MetricVec
 }
 }
 
 
 // NewCounterVec creates a new CounterVec based on the provided CounterOpts and
 // NewCounterVec creates a new CounterVec based on the provided CounterOpts and
-// partitioned by the given label names.
+// partitioned by the given label names. At least one label name must be
+// provided.
 func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
 func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
 	desc := NewDesc(
 	desc := NewDesc(
 		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
 		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
@@ -84,7 +96,7 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
 		opts.ConstLabels,
 		opts.ConstLabels,
 	)
 	)
 	return &CounterVec{
 	return &CounterVec{
-		metricVec: newMetricVec(desc, func(lvs ...string) Metric {
+		MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
 			result := &counter{value: value{
 			result := &counter{value: value{
 				desc:       desc,
 				desc:       desc,
 				valType:    CounterValue,
 				valType:    CounterValue,
@@ -96,51 +108,22 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
 	}
 	}
 }
 }
 
 
-// GetMetricWithLabelValues returns the Counter for the given slice of label
-// values (same order as the VariableLabels in Desc). If that combination of
-// label values is accessed for the first time, a new Counter is created.
-//
-// It is possible to call this method without using the returned Counter to only
-// create the new Counter but leave it at its starting value 0. See also the
-// SummaryVec example.
-//
-// Keeping the Counter for later use is possible (and should be considered if
-// performance is critical), but keep in mind that Reset, DeleteLabelValues and
-// Delete can be used to delete the Counter from the CounterVec. In that case,
-// the Counter will still exist, but it will not be exported anymore, even if a
-// Counter with the same label values is created later.
-//
-// An error is returned if the number of label values is not the same as the
-// number of VariableLabels in Desc.
-//
-// Note that for more than one label value, this method is prone to mistakes
-// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
-// an alternative to avoid that type of mistake. For higher label numbers, the
-// latter has a much more readable (albeit more verbose) syntax, but it comes
-// with a performance overhead (for creating and processing the Labels map).
-// See also the GaugeVec example.
+// GetMetricWithLabelValues replaces the method of the same name in
+// MetricVec. The difference is that this method returns a Counter and not a
+// Metric so that no type conversion is required.
 func (m *CounterVec) GetMetricWithLabelValues(lvs ...string) (Counter, error) {
 func (m *CounterVec) GetMetricWithLabelValues(lvs ...string) (Counter, error) {
-	metric, err := m.metricVec.getMetricWithLabelValues(lvs...)
+	metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...)
 	if metric != nil {
 	if metric != nil {
 		return metric.(Counter), err
 		return metric.(Counter), err
 	}
 	}
 	return nil, err
 	return nil, err
 }
 }
 
 
-// GetMetricWith returns the Counter for the given Labels map (the label names
-// must match those of the VariableLabels in Desc). If that label map is
-// accessed for the first time, a new Counter is created. Implications of
-// creating a Counter without using it and keeping the Counter for later use are
-// the same as for GetMetricWithLabelValues.
-//
-// An error is returned if the number and names of the Labels are inconsistent
-// with those of the VariableLabels in Desc.
-//
-// This method is used for the same purpose as
-// GetMetricWithLabelValues(...string). See there for pros and cons of the two
-// methods.
+// GetMetricWith replaces the method of the same name in MetricVec. The
+// difference is that this method returns a Counter and not a Metric so that no
+// type conversion is required.
 func (m *CounterVec) GetMetricWith(labels Labels) (Counter, error) {
 func (m *CounterVec) GetMetricWith(labels Labels) (Counter, error) {
-	metric, err := m.metricVec.getMetricWith(labels)
+	metric, err := m.MetricVec.GetMetricWith(labels)
 	if metric != nil {
 	if metric != nil {
 		return metric.(Counter), err
 		return metric.(Counter), err
 	}
 	}
@@ -152,14 +135,14 @@ func (m *CounterVec) GetMetricWith(labels Labels) (Counter, error) {
 // error, WithLabelValues allows shortcuts like
 // error, WithLabelValues allows shortcuts like
 //     myVec.WithLabelValues("404", "GET").Add(42)
 //     myVec.WithLabelValues("404", "GET").Add(42)
 func (m *CounterVec) WithLabelValues(lvs ...string) Counter {
 func (m *CounterVec) WithLabelValues(lvs ...string) Counter {
-	return m.metricVec.withLabelValues(lvs...).(Counter)
+	return m.MetricVec.WithLabelValues(lvs...).(Counter)
 }
 }
 
 
 // With works as GetMetricWith, but panics where GetMetricWithLabels would have
 // With works as GetMetricWith, but panics where GetMetricWithLabels would have
 // returned an error. By not returning an error, With allows shortcuts like
 // returned an error. By not returning an error, With allows shortcuts like
 //     myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
 //     myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
 func (m *CounterVec) With(labels Labels) Counter {
 func (m *CounterVec) With(labels Labels) Counter {
-	return m.metricVec.with(labels).(Counter)
+	return m.MetricVec.With(labels).(Counter)
 }
 }
 
 
 // CounterFunc is a Counter whose value is determined at collect time by calling a
 // CounterFunc is a Counter whose value is determined at collect time by calling a

+ 26 - 10
vendor/github.com/prometheus/client_golang/prometheus/desc.go

@@ -16,15 +16,33 @@ package prometheus
 import (
 import (
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
+	"regexp"
 	"sort"
 	"sort"
 	"strings"
 	"strings"
 
 
 	"github.com/golang/protobuf/proto"
 	"github.com/golang/protobuf/proto"
-	"github.com/prometheus/common/model"
 
 
 	dto "github.com/prometheus/client_model/go"
 	dto "github.com/prometheus/client_model/go"
 )
 )
 
 
+var (
+	metricNameRE = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_:]*$`)
+	labelNameRE  = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$")
+)
+
+// reservedLabelPrefix is a prefix which is not legal in user-supplied
+// label names.
+const reservedLabelPrefix = "__"
+
+// Labels represents a collection of label name -> value mappings. This type is
+// commonly used with the With(Labels) and GetMetricWith(Labels) methods of
+// metric vector Collectors, e.g.:
+//     myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
+//
+// The other use-case is the specification of constant label pairs in Opts or to
+// create a Desc.
+type Labels map[string]string
+
 // Desc is the descriptor used by every Prometheus Metric. It is essentially
 // Desc is the descriptor used by every Prometheus Metric. It is essentially
 // the immutable meta-data of a Metric. The normal Metric implementations
 // the immutable meta-data of a Metric. The normal Metric implementations
 // included in this package manage their Desc under the hood. Users only have to
 // included in this package manage their Desc under the hood. Users only have to
@@ -60,7 +78,7 @@ type Desc struct {
 	// Help string. Each Desc with the same fqName must have the same
 	// Help string. Each Desc with the same fqName must have the same
 	// dimHash.
 	// dimHash.
 	dimHash uint64
 	dimHash uint64
-	// err is an error that occurred during construction. It is reported on
+	// err is an error that occured during construction. It is reported on
 	// registration time.
 	// registration time.
 	err error
 	err error
 }
 }
@@ -85,7 +103,7 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *
 		d.err = errors.New("empty help string")
 		d.err = errors.New("empty help string")
 		return d
 		return d
 	}
 	}
-	if !model.IsValidMetricName(model.LabelValue(fqName)) {
+	if !metricNameRE.MatchString(fqName) {
 		d.err = fmt.Errorf("%q is not a valid metric name", fqName)
 		d.err = fmt.Errorf("%q is not a valid metric name", fqName)
 		return d
 		return d
 	}
 	}
@@ -109,12 +127,6 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *
 	for _, labelName := range labelNames {
 	for _, labelName := range labelNames {
 		labelValues = append(labelValues, constLabels[labelName])
 		labelValues = append(labelValues, constLabels[labelName])
 	}
 	}
-	// Validate the const label values. They can't have a wrong cardinality, so
-	// use in len(labelValues) as expectedNumberOfValues.
-	if err := validateLabelValues(labelValues, len(labelValues)); err != nil {
-		d.err = err
-		return d
-	}
 	// Now add the variable label names, but prefix them with something that
 	// Now add the variable label names, but prefix them with something that
 	// cannot be in a regular label name. That prevents matching the label
 	// cannot be in a regular label name. That prevents matching the label
 	// dimension with a different mix between preset and variable labels.
 	// dimension with a different mix between preset and variable labels.
@@ -130,7 +142,6 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *
 		d.err = errors.New("duplicate label names")
 		d.err = errors.New("duplicate label names")
 		return d
 		return d
 	}
 	}
-
 	vh := hashNew()
 	vh := hashNew()
 	for _, val := range labelValues {
 	for _, val := range labelValues {
 		vh = hashAdd(vh, val)
 		vh = hashAdd(vh, val)
@@ -187,3 +198,8 @@ func (d *Desc) String() string {
 		d.variableLabels,
 		d.variableLabels,
 	)
 	)
 }
 }
+
+func checkLabelName(l string) bool {
+	return labelNameRE.MatchString(l) &&
+		!strings.HasPrefix(l, reservedLabelPrefix)
+}

+ 32 - 37
vendor/github.com/prometheus/client_golang/prometheus/doc.go

@@ -17,7 +17,7 @@
 // Pushgateway (package push).
 // Pushgateway (package push).
 //
 //
 // All exported functions and methods are safe to be used concurrently unless
 // All exported functions and methods are safe to be used concurrently unless
-// specified otherwise.
+//specified otherwise.
 //
 //
 // A Basic Example
 // A Basic Example
 //
 //
@@ -26,7 +26,6 @@
 //    package main
 //    package main
 //
 //
 //    import (
 //    import (
-//    	"log"
 //    	"net/http"
 //    	"net/http"
 //
 //
 //    	"github.com/prometheus/client_golang/prometheus"
 //    	"github.com/prometheus/client_golang/prometheus"
@@ -60,7 +59,7 @@
 //    	// The Handler function provides a default handler to expose metrics
 //    	// The Handler function provides a default handler to expose metrics
 //    	// via an HTTP server. "/metrics" is the usual endpoint for that.
 //    	// via an HTTP server. "/metrics" is the usual endpoint for that.
 //    	http.Handle("/metrics", promhttp.Handler())
 //    	http.Handle("/metrics", promhttp.Handler())
-//    	log.Fatal(http.ListenAndServe(":8080", nil))
+//    	http.ListenAndServe(":8080", nil)
 //    }
 //    }
 //
 //
 //
 //
@@ -70,7 +69,7 @@
 // Metrics
 // Metrics
 //
 //
 // The number of exported identifiers in this package might appear a bit
 // The number of exported identifiers in this package might appear a bit
-// overwhelming. However, in addition to the basic plumbing shown in the example
+// overwhelming. Hovever, in addition to the basic plumbing shown in the example
 // above, you only need to understand the different metric types and their
 // above, you only need to understand the different metric types and their
 // vector versions for basic usage.
 // vector versions for basic usage.
 //
 //
@@ -96,8 +95,8 @@
 // SummaryVec, HistogramVec, and UntypedVec are not.
 // SummaryVec, HistogramVec, and UntypedVec are not.
 //
 //
 // To create instances of Metrics and their vector versions, you need a suitable
 // To create instances of Metrics and their vector versions, you need a suitable
-// …Opts struct, i.e. GaugeOpts, CounterOpts, SummaryOpts, HistogramOpts, or
-// UntypedOpts.
+// …Opts struct, i.e. GaugeOpts, CounterOpts, SummaryOpts,
+// HistogramOpts, or UntypedOpts.
 //
 //
 // Custom Collectors and constant Metrics
 // Custom Collectors and constant Metrics
 //
 //
@@ -115,8 +114,8 @@
 // Metric instances “on the fly” using NewConstMetric, NewConstHistogram, and
 // Metric instances “on the fly” using NewConstMetric, NewConstHistogram, and
 // NewConstSummary (and their respective Must… versions). That will happen in
 // NewConstSummary (and their respective Must… versions). That will happen in
 // the Collect method. The Describe method has to return separate Desc
 // the Collect method. The Describe method has to return separate Desc
-// instances, representative of the “throw-away” metrics to be created later.
-// NewDesc comes in handy to create those Desc instances.
+// instances, representative of the “throw-away” metrics to be created
+// later. NewDesc comes in handy to create those Desc instances.
 //
 //
 // The Collector example illustrates the use case. You can also look at the
 // The Collector example illustrates the use case. You can also look at the
 // source code of the processCollector (mirroring process metrics), the
 // source code of the processCollector (mirroring process metrics), the
@@ -130,34 +129,34 @@
 // Advanced Uses of the Registry
 // Advanced Uses of the Registry
 //
 //
 // While MustRegister is the by far most common way of registering a Collector,
 // While MustRegister is the by far most common way of registering a Collector,
-// sometimes you might want to handle the errors the registration might cause.
-// As suggested by the name, MustRegister panics if an error occurs. With the
-// Register function, the error is returned and can be handled.
+// sometimes you might want to handle the errors the registration might
+// cause. As suggested by the name, MustRegister panics if an error occurs. With
+// the Register function, the error is returned and can be handled.
 //
 //
 // An error is returned if the registered Collector is incompatible or
 // An error is returned if the registered Collector is incompatible or
 // inconsistent with already registered metrics. The registry aims for
 // inconsistent with already registered metrics. The registry aims for
-// consistency of the collected metrics according to the Prometheus data model.
-// Inconsistencies are ideally detected at registration time, not at collect
-// time. The former will usually be detected at start-up time of a program,
-// while the latter will only happen at scrape time, possibly not even on the
-// first scrape if the inconsistency only becomes relevant later. That is the
-// main reason why a Collector and a Metric have to describe themselves to the
-// registry.
+// consistency of the collected metrics according to the Prometheus data
+// model. Inconsistencies are ideally detected at registration time, not at
+// collect time. The former will usually be detected at start-up time of a
+// program, while the latter will only happen at scrape time, possibly not even
+// on the first scrape if the inconsistency only becomes relevant later. That is
+// the main reason why a Collector and a Metric have to describe themselves to
+// the registry.
 //
 //
 // So far, everything we did operated on the so-called default registry, as it
 // So far, everything we did operated on the so-called default registry, as it
-// can be found in the global DefaultRegisterer variable. With NewRegistry, you
+// can be found in the global DefaultRegistry variable. With NewRegistry, you
 // can create a custom registry, or you can even implement the Registerer or
 // can create a custom registry, or you can even implement the Registerer or
-// Gatherer interfaces yourself. The methods Register and Unregister work in the
-// same way on a custom registry as the global functions Register and Unregister
-// on the default registry.
-//
-// There are a number of uses for custom registries: You can use registries with
-// special properties, see NewPedanticRegistry. You can avoid global state, as
-// it is imposed by the DefaultRegisterer. You can use multiple registries at
-// the same time to expose different metrics in different ways.  You can use
+// Gatherer interfaces yourself. The methods Register and Unregister work in
+// the same way on a custom registry as the global functions Register and
+// Unregister on the default registry.
+//
+// There are a number of uses for custom registries: You can use registries
+// with special properties, see NewPedanticRegistry. You can avoid global state,
+// as it is imposed by the DefaultRegistry. You can use multiple registries at
+// the same time to expose different metrics in different ways. You can use
 // separate registries for testing purposes.
 // separate registries for testing purposes.
 //
 //
-// Also note that the DefaultRegisterer comes registered with a Collector for Go
+// Also note that the DefaultRegistry comes registered with a Collector for Go
 // runtime metrics (via NewGoCollector) and a Collector for process metrics (via
 // runtime metrics (via NewGoCollector) and a Collector for process metrics (via
 // NewProcessCollector). With a custom registry, you are in control and decide
 // NewProcessCollector). With a custom registry, you are in control and decide
 // yourself about the Collectors to register.
 // yourself about the Collectors to register.
@@ -167,20 +166,16 @@
 // The Registry implements the Gatherer interface. The caller of the Gather
 // The Registry implements the Gatherer interface. The caller of the Gather
 // method can then expose the gathered metrics in some way. Usually, the metrics
 // method can then expose the gathered metrics in some way. Usually, the metrics
 // are served via HTTP on the /metrics endpoint. That's happening in the example
 // are served via HTTP on the /metrics endpoint. That's happening in the example
-// above. The tools to expose metrics via HTTP are in the promhttp sub-package.
-// (The top-level functions in the prometheus package are deprecated.)
+// above. The tools to expose metrics via HTTP are in the promhttp
+// sub-package. (The top-level functions in the prometheus package are
+// deprecated.)
 //
 //
 // Pushing to the Pushgateway
 // Pushing to the Pushgateway
 //
 //
 // Function for pushing to the Pushgateway can be found in the push sub-package.
 // Function for pushing to the Pushgateway can be found in the push sub-package.
 //
 //
-// Graphite Bridge
-//
-// Functions and examples to push metrics from a Gatherer to Graphite can be
-// found in the graphite sub-package.
-//
 // Other Means of Exposition
 // Other Means of Exposition
 //
 //
-// More ways of exposing metrics can easily be added by following the approaches
-// of the existing implementations.
+// More ways of exposing metrics can easily be added. Sending metrics to
+// Graphite would be an example that will soon be implemented.
 package prometheus
 package prometheus

+ 18 - 51
vendor/github.com/prometheus/client_golang/prometheus/gauge.go

@@ -27,21 +27,16 @@ type Gauge interface {
 
 
 	// Set sets the Gauge to an arbitrary value.
 	// Set sets the Gauge to an arbitrary value.
 	Set(float64)
 	Set(float64)
-	// Inc increments the Gauge by 1. Use Add to increment it by arbitrary
-	// values.
+	// Inc increments the Gauge by 1.
 	Inc()
 	Inc()
-	// Dec decrements the Gauge by 1. Use Sub to decrement it by arbitrary
-	// values.
+	// Dec decrements the Gauge by 1.
 	Dec()
 	Dec()
-	// Add adds the given value to the Gauge. (The value can be negative,
-	// resulting in a decrease of the Gauge.)
+	// Add adds the given value to the Gauge. (The value can be
+	// negative, resulting in a decrease of the Gauge.)
 	Add(float64)
 	Add(float64)
 	// Sub subtracts the given value from the Gauge. (The value can be
 	// Sub subtracts the given value from the Gauge. (The value can be
 	// negative, resulting in an increase of the Gauge.)
 	// negative, resulting in an increase of the Gauge.)
 	Sub(float64)
 	Sub(float64)
-
-	// SetToCurrentTime sets the Gauge to the current Unix time in seconds.
-	SetToCurrentTime()
 }
 }
 
 
 // GaugeOpts is an alias for Opts. See there for doc comments.
 // GaugeOpts is an alias for Opts. See there for doc comments.
@@ -63,11 +58,12 @@ func NewGauge(opts GaugeOpts) Gauge {
 // (e.g. number of operations queued, partitioned by user and operation
 // (e.g. number of operations queued, partitioned by user and operation
 // type). Create instances with NewGaugeVec.
 // type). Create instances with NewGaugeVec.
 type GaugeVec struct {
 type GaugeVec struct {
-	*metricVec
+	*MetricVec
 }
 }
 
 
 // NewGaugeVec creates a new GaugeVec based on the provided GaugeOpts and
 // NewGaugeVec creates a new GaugeVec based on the provided GaugeOpts and
-// partitioned by the given label names.
+// partitioned by the given label names. At least one label name must be
+// provided.
 func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec {
 func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec {
 	desc := NewDesc(
 	desc := NewDesc(
 		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
 		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
@@ -76,57 +72,28 @@ func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec {
 		opts.ConstLabels,
 		opts.ConstLabels,
 	)
 	)
 	return &GaugeVec{
 	return &GaugeVec{
-		metricVec: newMetricVec(desc, func(lvs ...string) Metric {
+		MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
 			return newValue(desc, GaugeValue, 0, lvs...)
 			return newValue(desc, GaugeValue, 0, lvs...)
 		}),
 		}),
 	}
 	}
 }
 }
 
 
-// GetMetricWithLabelValues returns the Gauge for the given slice of label
-// values (same order as the VariableLabels in Desc). If that combination of
-// label values is accessed for the first time, a new Gauge is created.
-//
-// It is possible to call this method without using the returned Gauge to only
-// create the new Gauge but leave it at its starting value 0. See also the
-// SummaryVec example.
-//
-// Keeping the Gauge for later use is possible (and should be considered if
-// performance is critical), but keep in mind that Reset, DeleteLabelValues and
-// Delete can be used to delete the Gauge from the GaugeVec. In that case, the
-// Gauge will still exist, but it will not be exported anymore, even if a
-// Gauge with the same label values is created later. See also the CounterVec
-// example.
-//
-// An error is returned if the number of label values is not the same as the
-// number of VariableLabels in Desc.
-//
-// Note that for more than one label value, this method is prone to mistakes
-// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
-// an alternative to avoid that type of mistake. For higher label numbers, the
-// latter has a much more readable (albeit more verbose) syntax, but it comes
-// with a performance overhead (for creating and processing the Labels map).
+// GetMetricWithLabelValues replaces the method of the same name in
+// MetricVec. The difference is that this method returns a Gauge and not a
+// Metric so that no type conversion is required.
 func (m *GaugeVec) GetMetricWithLabelValues(lvs ...string) (Gauge, error) {
 func (m *GaugeVec) GetMetricWithLabelValues(lvs ...string) (Gauge, error) {
-	metric, err := m.metricVec.getMetricWithLabelValues(lvs...)
+	metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...)
 	if metric != nil {
 	if metric != nil {
 		return metric.(Gauge), err
 		return metric.(Gauge), err
 	}
 	}
 	return nil, err
 	return nil, err
 }
 }
 
 
-// GetMetricWith returns the Gauge for the given Labels map (the label names
-// must match those of the VariableLabels in Desc). If that label map is
-// accessed for the first time, a new Gauge is created. Implications of
-// creating a Gauge without using it and keeping the Gauge for later use are
-// the same as for GetMetricWithLabelValues.
-//
-// An error is returned if the number and names of the Labels are inconsistent
-// with those of the VariableLabels in Desc.
-//
-// This method is used for the same purpose as
-// GetMetricWithLabelValues(...string). See there for pros and cons of the two
-// methods.
+// GetMetricWith replaces the method of the same name in MetricVec. The
+// difference is that this method returns a Gauge and not a Metric so that no
+// type conversion is required.
 func (m *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) {
 func (m *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) {
-	metric, err := m.metricVec.getMetricWith(labels)
+	metric, err := m.MetricVec.GetMetricWith(labels)
 	if metric != nil {
 	if metric != nil {
 		return metric.(Gauge), err
 		return metric.(Gauge), err
 	}
 	}
@@ -138,14 +105,14 @@ func (m *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) {
 // error, WithLabelValues allows shortcuts like
 // error, WithLabelValues allows shortcuts like
 //     myVec.WithLabelValues("404", "GET").Add(42)
 //     myVec.WithLabelValues("404", "GET").Add(42)
 func (m *GaugeVec) WithLabelValues(lvs ...string) Gauge {
 func (m *GaugeVec) WithLabelValues(lvs ...string) Gauge {
-	return m.metricVec.withLabelValues(lvs...).(Gauge)
+	return m.MetricVec.WithLabelValues(lvs...).(Gauge)
 }
 }
 
 
 // With works as GetMetricWith, but panics where GetMetricWithLabels would have
 // With works as GetMetricWith, but panics where GetMetricWithLabels would have
 // returned an error. By not returning an error, With allows shortcuts like
 // returned an error. By not returning an error, With allows shortcuts like
 //     myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
 //     myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
 func (m *GaugeVec) With(labels Labels) Gauge {
 func (m *GaugeVec) With(labels Labels) Gauge {
-	return m.metricVec.with(labels).(Gauge)
+	return m.MetricVec.With(labels).(Gauge)
 }
 }
 
 
 // GaugeFunc is a Gauge whose value is determined at collect time by calling a
 // GaugeFunc is a Gauge whose value is determined at collect time by calling a

+ 15 - 36
vendor/github.com/prometheus/client_golang/prometheus/go_collector.go

@@ -8,10 +8,8 @@ import (
 )
 )
 
 
 type goCollector struct {
 type goCollector struct {
-	goroutinesDesc *Desc
-	threadsDesc    *Desc
-	gcDesc         *Desc
-	goInfoDesc     *Desc
+	goroutines Gauge
+	gcDesc     *Desc
 
 
 	// metrics to describe and collect
 	// metrics to describe and collect
 	metrics memStatsMetrics
 	metrics memStatsMetrics
@@ -21,22 +19,15 @@ type goCollector struct {
 // go process.
 // go process.
 func NewGoCollector() Collector {
 func NewGoCollector() Collector {
 	return &goCollector{
 	return &goCollector{
-		goroutinesDesc: NewDesc(
-			"go_goroutines",
-			"Number of goroutines that currently exist.",
-			nil, nil),
-		threadsDesc: NewDesc(
-			"go_threads",
-			"Number of OS threads created.",
-			nil, nil),
+		goroutines: NewGauge(GaugeOpts{
+			Namespace: "go",
+			Name:      "goroutines",
+			Help:      "Number of goroutines that currently exist.",
+		}),
 		gcDesc: NewDesc(
 		gcDesc: NewDesc(
 			"go_gc_duration_seconds",
 			"go_gc_duration_seconds",
 			"A summary of the GC invocation durations.",
 			"A summary of the GC invocation durations.",
 			nil, nil),
 			nil, nil),
-		goInfoDesc: NewDesc(
-			"go_info",
-			"Information about the Go environment.",
-			nil, Labels{"version": runtime.Version()}),
 		metrics: memStatsMetrics{
 		metrics: memStatsMetrics{
 			{
 			{
 				desc: NewDesc(
 				desc: NewDesc(
@@ -57,7 +48,7 @@ func NewGoCollector() Collector {
 			}, {
 			}, {
 				desc: NewDesc(
 				desc: NewDesc(
 					memstatNamespace("sys_bytes"),
 					memstatNamespace("sys_bytes"),
-					"Number of bytes obtained from system.",
+					"Number of bytes obtained by system. Sum of all system allocations.",
 					nil, nil,
 					nil, nil,
 				),
 				),
 				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.Sys) },
 				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.Sys) },
@@ -120,12 +111,12 @@ func NewGoCollector() Collector {
 				valType: GaugeValue,
 				valType: GaugeValue,
 			}, {
 			}, {
 				desc: NewDesc(
 				desc: NewDesc(
-					memstatNamespace("heap_released_bytes"),
-					"Number of heap bytes released to OS.",
+					memstatNamespace("heap_released_bytes_total"),
+					"Total number of heap bytes released to OS.",
 					nil, nil,
 					nil, nil,
 				),
 				),
 				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.HeapReleased) },
 				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.HeapReleased) },
-				valType: GaugeValue,
+				valType: CounterValue,
 			}, {
 			}, {
 				desc: NewDesc(
 				desc: NewDesc(
 					memstatNamespace("heap_objects"),
 					memstatNamespace("heap_objects"),
@@ -222,14 +213,6 @@ func NewGoCollector() Collector {
 				),
 				),
 				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.LastGC) / 1e9 },
 				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.LastGC) / 1e9 },
 				valType: GaugeValue,
 				valType: GaugeValue,
-			}, {
-				desc: NewDesc(
-					memstatNamespace("gc_cpu_fraction"),
-					"The fraction of this program's available CPU time used by the GC since the program started.",
-					nil, nil,
-				),
-				eval:    func(ms *runtime.MemStats) float64 { return ms.GCCPUFraction },
-				valType: GaugeValue,
 			},
 			},
 		},
 		},
 	}
 	}
@@ -241,10 +224,9 @@ func memstatNamespace(s string) string {
 
 
 // Describe returns all descriptions of the collector.
 // Describe returns all descriptions of the collector.
 func (c *goCollector) Describe(ch chan<- *Desc) {
 func (c *goCollector) Describe(ch chan<- *Desc) {
-	ch <- c.goroutinesDesc
-	ch <- c.threadsDesc
+	ch <- c.goroutines.Desc()
 	ch <- c.gcDesc
 	ch <- c.gcDesc
-	ch <- c.goInfoDesc
+
 	for _, i := range c.metrics {
 	for _, i := range c.metrics {
 		ch <- i.desc
 		ch <- i.desc
 	}
 	}
@@ -252,9 +234,8 @@ func (c *goCollector) Describe(ch chan<- *Desc) {
 
 
 // Collect returns the current state of all metrics of the collector.
 // Collect returns the current state of all metrics of the collector.
 func (c *goCollector) Collect(ch chan<- Metric) {
 func (c *goCollector) Collect(ch chan<- Metric) {
-	ch <- MustNewConstMetric(c.goroutinesDesc, GaugeValue, float64(runtime.NumGoroutine()))
-	n, _ := runtime.ThreadCreateProfile(nil)
-	ch <- MustNewConstMetric(c.threadsDesc, GaugeValue, float64(n))
+	c.goroutines.Set(float64(runtime.NumGoroutine()))
+	ch <- c.goroutines
 
 
 	var stats debug.GCStats
 	var stats debug.GCStats
 	stats.PauseQuantiles = make([]time.Duration, 5)
 	stats.PauseQuantiles = make([]time.Duration, 5)
@@ -267,8 +248,6 @@ func (c *goCollector) Collect(ch chan<- Metric) {
 	quantiles[0.0] = stats.PauseQuantiles[0].Seconds()
 	quantiles[0.0] = stats.PauseQuantiles[0].Seconds()
 	ch <- MustNewConstSummary(c.gcDesc, uint64(stats.NumGC), float64(stats.PauseTotal.Seconds()), quantiles)
 	ch <- MustNewConstSummary(c.gcDesc, uint64(stats.NumGC), float64(stats.PauseTotal.Seconds()), quantiles)
 
 
-	ch <- MustNewConstMetric(c.goInfoDesc, GaugeValue, 1)
-
 	ms := &runtime.MemStats{}
 	ms := &runtime.MemStats{}
 	runtime.ReadMemStats(ms)
 	runtime.ReadMemStats(ms)
 	for _, i := range c.metrics {
 	for _, i := range c.metrics {

+ 22 - 51
vendor/github.com/prometheus/client_golang/prometheus/histogram.go

@@ -287,11 +287,12 @@ func (h *histogram) Write(out *dto.Metric) error {
 // (e.g. HTTP request latencies, partitioned by status code and method). Create
 // (e.g. HTTP request latencies, partitioned by status code and method). Create
 // instances with NewHistogramVec.
 // instances with NewHistogramVec.
 type HistogramVec struct {
 type HistogramVec struct {
-	*metricVec
+	*MetricVec
 }
 }
 
 
 // NewHistogramVec creates a new HistogramVec based on the provided HistogramOpts and
 // NewHistogramVec creates a new HistogramVec based on the provided HistogramOpts and
-// partitioned by the given label names.
+// partitioned by the given label names. At least one label name must be
+// provided.
 func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec {
 func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec {
 	desc := NewDesc(
 	desc := NewDesc(
 		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
 		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
@@ -300,60 +301,30 @@ func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec {
 		opts.ConstLabels,
 		opts.ConstLabels,
 	)
 	)
 	return &HistogramVec{
 	return &HistogramVec{
-		metricVec: newMetricVec(desc, func(lvs ...string) Metric {
+		MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
 			return newHistogram(desc, opts, lvs...)
 			return newHistogram(desc, opts, lvs...)
 		}),
 		}),
 	}
 	}
 }
 }
 
 
-// GetMetricWithLabelValues returns the Histogram for the given slice of label
-// values (same order as the VariableLabels in Desc). If that combination of
-// label values is accessed for the first time, a new Histogram is created.
-//
-// It is possible to call this method without using the returned Histogram to only
-// create the new Histogram but leave it at its starting value, a Histogram without
-// any observations.
-//
-// Keeping the Histogram for later use is possible (and should be considered if
-// performance is critical), but keep in mind that Reset, DeleteLabelValues and
-// Delete can be used to delete the Histogram from the HistogramVec. In that case, the
-// Histogram will still exist, but it will not be exported anymore, even if a
-// Histogram with the same label values is created later. See also the CounterVec
-// example.
-//
-// An error is returned if the number of label values is not the same as the
-// number of VariableLabels in Desc.
-//
-// Note that for more than one label value, this method is prone to mistakes
-// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
-// an alternative to avoid that type of mistake. For higher label numbers, the
-// latter has a much more readable (albeit more verbose) syntax, but it comes
-// with a performance overhead (for creating and processing the Labels map).
-// See also the GaugeVec example.
-func (m *HistogramVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) {
-	metric, err := m.metricVec.getMetricWithLabelValues(lvs...)
+// GetMetricWithLabelValues replaces the method of the same name in
+// MetricVec. The difference is that this method returns a Histogram and not a
+// Metric so that no type conversion is required.
+func (m *HistogramVec) GetMetricWithLabelValues(lvs ...string) (Histogram, error) {
+	metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...)
 	if metric != nil {
 	if metric != nil {
-		return metric.(Observer), err
+		return metric.(Histogram), err
 	}
 	}
 	return nil, err
 	return nil, err
 }
 }
 
 
-// GetMetricWith returns the Histogram for the given Labels map (the label names
-// must match those of the VariableLabels in Desc). If that label map is
-// accessed for the first time, a new Histogram is created. Implications of
-// creating a Histogram without using it and keeping the Histogram for later use
-// are the same as for GetMetricWithLabelValues.
-//
-// An error is returned if the number and names of the Labels are inconsistent
-// with those of the VariableLabels in Desc.
-//
-// This method is used for the same purpose as
-// GetMetricWithLabelValues(...string). See there for pros and cons of the two
-// methods.
-func (m *HistogramVec) GetMetricWith(labels Labels) (Observer, error) {
-	metric, err := m.metricVec.getMetricWith(labels)
+// GetMetricWith replaces the method of the same name in MetricVec. The
+// difference is that this method returns a Histogram and not a Metric so that no
+// type conversion is required.
+func (m *HistogramVec) GetMetricWith(labels Labels) (Histogram, error) {
+	metric, err := m.MetricVec.GetMetricWith(labels)
 	if metric != nil {
 	if metric != nil {
-		return metric.(Observer), err
+		return metric.(Histogram), err
 	}
 	}
 	return nil, err
 	return nil, err
 }
 }
@@ -362,15 +333,15 @@ func (m *HistogramVec) GetMetricWith(labels Labels) (Observer, error) {
 // GetMetricWithLabelValues would have returned an error. By not returning an
 // GetMetricWithLabelValues would have returned an error. By not returning an
 // error, WithLabelValues allows shortcuts like
 // error, WithLabelValues allows shortcuts like
 //     myVec.WithLabelValues("404", "GET").Observe(42.21)
 //     myVec.WithLabelValues("404", "GET").Observe(42.21)
-func (m *HistogramVec) WithLabelValues(lvs ...string) Observer {
-	return m.metricVec.withLabelValues(lvs...).(Observer)
+func (m *HistogramVec) WithLabelValues(lvs ...string) Histogram {
+	return m.MetricVec.WithLabelValues(lvs...).(Histogram)
 }
 }
 
 
 // With works as GetMetricWith, but panics where GetMetricWithLabels would have
 // With works as GetMetricWith, but panics where GetMetricWithLabels would have
 // returned an error. By not returning an error, With allows shortcuts like
 // returned an error. By not returning an error, With allows shortcuts like
 //     myVec.With(Labels{"code": "404", "method": "GET"}).Observe(42.21)
 //     myVec.With(Labels{"code": "404", "method": "GET"}).Observe(42.21)
-func (m *HistogramVec) With(labels Labels) Observer {
-	return m.metricVec.with(labels).(Observer)
+func (m *HistogramVec) With(labels Labels) Histogram {
+	return m.MetricVec.With(labels).(Histogram)
 }
 }
 
 
 type constHistogram struct {
 type constHistogram struct {
@@ -430,8 +401,8 @@ func NewConstHistogram(
 	buckets map[float64]uint64,
 	buckets map[float64]uint64,
 	labelValues ...string,
 	labelValues ...string,
 ) (Metric, error) {
 ) (Metric, error) {
-	if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil {
-		return nil, err
+	if len(desc.variableLabels) != len(labelValues) {
+		return nil, errInconsistentCardinality
 	}
 	}
 	return &constHistogram{
 	return &constHistogram{
 		desc:       desc,
 		desc:       desc,

+ 38 - 72
vendor/github.com/prometheus/client_golang/prometheus/http.go

@@ -62,8 +62,7 @@ func giveBuf(buf *bytes.Buffer) {
 //
 //
 // Deprecated: Please note the issues described in the doc comment of
 // Deprecated: Please note the issues described in the doc comment of
 // InstrumentHandler. You might want to consider using promhttp.Handler instead
 // InstrumentHandler. You might want to consider using promhttp.Handler instead
-// (which is not instrumented, but can be instrumented with the tooling provided
-// in package promhttp).
+// (which is non instrumented).
 func Handler() http.Handler {
 func Handler() http.Handler {
 	return InstrumentHandler("prometheus", UninstrumentedHandler())
 	return InstrumentHandler("prometheus", UninstrumentedHandler())
 }
 }
@@ -96,7 +95,7 @@ func UninstrumentedHandler() http.Handler {
 			closer.Close()
 			closer.Close()
 		}
 		}
 		if lastErr != nil && buf.Len() == 0 {
 		if lastErr != nil && buf.Len() == 0 {
-			http.Error(w, "No metrics encoded, last error:\n\n"+lastErr.Error(), http.StatusInternalServerError)
+			http.Error(w, "No metrics encoded, last error:\n\n"+err.Error(), http.StatusInternalServerError)
 			return
 			return
 		}
 		}
 		header := w.Header()
 		header := w.Header()
@@ -159,8 +158,7 @@ func nowSeries(t ...time.Time) nower {
 // value. http_requests_total is a metric vector partitioned by HTTP method
 // value. http_requests_total is a metric vector partitioned by HTTP method
 // (label name "method") and HTTP status code (label name "code").
 // (label name "method") and HTTP status code (label name "code").
 //
 //
-// Deprecated: InstrumentHandler has several issues. Use the tooling provided in
-// package promhttp instead. The issues are the following:
+// Deprecated: InstrumentHandler has several issues:
 //
 //
 // - It uses Summaries rather than Histograms. Summaries are not useful if
 // - It uses Summaries rather than Histograms. Summaries are not useful if
 // aggregation across multiple instances is required.
 // aggregation across multiple instances is required.
@@ -174,8 +172,9 @@ func nowSeries(t ...time.Time) nower {
 // httputil.ReverseProxy is a prominent example for a handler
 // httputil.ReverseProxy is a prominent example for a handler
 // performing such writes.
 // performing such writes.
 //
 //
-// - It has additional issues with HTTP/2, cf.
-// https://github.com/prometheus/client_golang/issues/272.
+// Upcoming versions of this package will provide ways of instrumenting HTTP
+// handlers that are more flexible and have fewer issues. Please prefer direct
+// instrumentation in the meantime.
 func InstrumentHandler(handlerName string, handler http.Handler) http.HandlerFunc {
 func InstrumentHandler(handlerName string, handler http.Handler) http.HandlerFunc {
 	return InstrumentHandlerFunc(handlerName, handler.ServeHTTP)
 	return InstrumentHandlerFunc(handlerName, handler.ServeHTTP)
 }
 }
@@ -185,13 +184,12 @@ func InstrumentHandler(handlerName string, handler http.Handler) http.HandlerFun
 // issues).
 // issues).
 //
 //
 // Deprecated: InstrumentHandlerFunc is deprecated for the same reasons as
 // Deprecated: InstrumentHandlerFunc is deprecated for the same reasons as
-// InstrumentHandler is. Use the tooling provided in package promhttp instead.
+// InstrumentHandler is.
 func InstrumentHandlerFunc(handlerName string, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
 func InstrumentHandlerFunc(handlerName string, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
 	return InstrumentHandlerFuncWithOpts(
 	return InstrumentHandlerFuncWithOpts(
 		SummaryOpts{
 		SummaryOpts{
 			Subsystem:   "http",
 			Subsystem:   "http",
 			ConstLabels: Labels{"handler": handlerName},
 			ConstLabels: Labels{"handler": handlerName},
-			Objectives:  map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
 		},
 		},
 		handlerFunc,
 		handlerFunc,
 	)
 	)
@@ -224,7 +222,7 @@ func InstrumentHandlerFunc(handlerName string, handlerFunc func(http.ResponseWri
 // SummaryOpts.
 // SummaryOpts.
 //
 //
 // Deprecated: InstrumentHandlerWithOpts is deprecated for the same reasons as
 // Deprecated: InstrumentHandlerWithOpts is deprecated for the same reasons as
-// InstrumentHandler is. Use the tooling provided in package promhttp instead.
+// InstrumentHandler is.
 func InstrumentHandlerWithOpts(opts SummaryOpts, handler http.Handler) http.HandlerFunc {
 func InstrumentHandlerWithOpts(opts SummaryOpts, handler http.Handler) http.HandlerFunc {
 	return InstrumentHandlerFuncWithOpts(opts, handler.ServeHTTP)
 	return InstrumentHandlerFuncWithOpts(opts, handler.ServeHTTP)
 }
 }
@@ -235,7 +233,7 @@ func InstrumentHandlerWithOpts(opts SummaryOpts, handler http.Handler) http.Hand
 // SummaryOpts are used.
 // SummaryOpts are used.
 //
 //
 // Deprecated: InstrumentHandlerFuncWithOpts is deprecated for the same reasons
 // Deprecated: InstrumentHandlerFuncWithOpts is deprecated for the same reasons
-// as InstrumentHandler is. Use the tooling provided in package promhttp instead.
+// as InstrumentHandler is.
 func InstrumentHandlerFuncWithOpts(opts SummaryOpts, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
 func InstrumentHandlerFuncWithOpts(opts SummaryOpts, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
 	reqCnt := NewCounterVec(
 	reqCnt := NewCounterVec(
 		CounterOpts{
 		CounterOpts{
@@ -247,52 +245,34 @@ func InstrumentHandlerFuncWithOpts(opts SummaryOpts, handlerFunc func(http.Respo
 		},
 		},
 		instLabels,
 		instLabels,
 	)
 	)
-	if err := Register(reqCnt); err != nil {
-		if are, ok := err.(AlreadyRegisteredError); ok {
-			reqCnt = are.ExistingCollector.(*CounterVec)
-		} else {
-			panic(err)
-		}
-	}
 
 
 	opts.Name = "request_duration_microseconds"
 	opts.Name = "request_duration_microseconds"
 	opts.Help = "The HTTP request latencies in microseconds."
 	opts.Help = "The HTTP request latencies in microseconds."
 	reqDur := NewSummary(opts)
 	reqDur := NewSummary(opts)
-	if err := Register(reqDur); err != nil {
-		if are, ok := err.(AlreadyRegisteredError); ok {
-			reqDur = are.ExistingCollector.(Summary)
-		} else {
-			panic(err)
-		}
-	}
 
 
 	opts.Name = "request_size_bytes"
 	opts.Name = "request_size_bytes"
 	opts.Help = "The HTTP request sizes in bytes."
 	opts.Help = "The HTTP request sizes in bytes."
 	reqSz := NewSummary(opts)
 	reqSz := NewSummary(opts)
-	if err := Register(reqSz); err != nil {
-		if are, ok := err.(AlreadyRegisteredError); ok {
-			reqSz = are.ExistingCollector.(Summary)
-		} else {
-			panic(err)
-		}
-	}
 
 
 	opts.Name = "response_size_bytes"
 	opts.Name = "response_size_bytes"
 	opts.Help = "The HTTP response sizes in bytes."
 	opts.Help = "The HTTP response sizes in bytes."
 	resSz := NewSummary(opts)
 	resSz := NewSummary(opts)
-	if err := Register(resSz); err != nil {
-		if are, ok := err.(AlreadyRegisteredError); ok {
-			resSz = are.ExistingCollector.(Summary)
-		} else {
-			panic(err)
-		}
-	}
+
+	regReqCnt := MustRegisterOrGet(reqCnt).(*CounterVec)
+	regReqDur := MustRegisterOrGet(reqDur).(Summary)
+	regReqSz := MustRegisterOrGet(reqSz).(Summary)
+	regResSz := MustRegisterOrGet(resSz).(Summary)
 
 
 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		now := time.Now()
 		now := time.Now()
 
 
 		delegate := &responseWriterDelegator{ResponseWriter: w}
 		delegate := &responseWriterDelegator{ResponseWriter: w}
-		out := computeApproximateRequestSize(r)
+		out := make(chan int)
+		urlLen := 0
+		if r.URL != nil {
+			urlLen = len(r.URL.String())
+		}
+		go computeApproximateRequestSize(r, out, urlLen)
 
 
 		_, cn := w.(http.CloseNotifier)
 		_, cn := w.(http.CloseNotifier)
 		_, fl := w.(http.Flusher)
 		_, fl := w.(http.Flusher)
@@ -310,44 +290,30 @@ func InstrumentHandlerFuncWithOpts(opts SummaryOpts, handlerFunc func(http.Respo
 
 
 		method := sanitizeMethod(r.Method)
 		method := sanitizeMethod(r.Method)
 		code := sanitizeCode(delegate.status)
 		code := sanitizeCode(delegate.status)
-		reqCnt.WithLabelValues(method, code).Inc()
-		reqDur.Observe(elapsed)
-		resSz.Observe(float64(delegate.written))
-		reqSz.Observe(float64(<-out))
+		regReqCnt.WithLabelValues(method, code).Inc()
+		regReqDur.Observe(elapsed)
+		regResSz.Observe(float64(delegate.written))
+		regReqSz.Observe(float64(<-out))
 	})
 	})
 }
 }
 
 
-func computeApproximateRequestSize(r *http.Request) <-chan int {
-	// Get URL length in current go routine for avoiding a race condition.
-	// HandlerFunc that runs in parallel may modify the URL.
-	s := 0
-	if r.URL != nil {
-		s += len(r.URL.String())
-	}
-
-	out := make(chan int, 1)
-
-	go func() {
-		s += len(r.Method)
-		s += len(r.Proto)
-		for name, values := range r.Header {
-			s += len(name)
-			for _, value := range values {
-				s += len(value)
-			}
+func computeApproximateRequestSize(r *http.Request, out chan int, s int) {
+	s += len(r.Method)
+	s += len(r.Proto)
+	for name, values := range r.Header {
+		s += len(name)
+		for _, value := range values {
+			s += len(value)
 		}
 		}
-		s += len(r.Host)
+	}
+	s += len(r.Host)
 
 
-		// N.B. r.Form and r.MultipartForm are assumed to be included in r.URL.
+	// N.B. r.Form and r.MultipartForm are assumed to be included in r.URL.
 
 
-		if r.ContentLength != -1 {
-			s += int(r.ContentLength)
-		}
-		out <- s
-		close(out)
-	}()
-
-	return out
+	if r.ContentLength != -1 {
+		s += int(r.ContentLength)
+	}
+	out <- s
 }
 }
 
 
 type responseWriterDelegator struct {
 type responseWriterDelegator struct {

+ 0 - 57
vendor/github.com/prometheus/client_golang/prometheus/labels.go

@@ -1,57 +0,0 @@
-package prometheus
-
-import (
-	"errors"
-	"fmt"
-	"strings"
-	"unicode/utf8"
-
-	"github.com/prometheus/common/model"
-)
-
-// Labels represents a collection of label name -> value mappings. This type is
-// commonly used with the With(Labels) and GetMetricWith(Labels) methods of
-// metric vector Collectors, e.g.:
-//     myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
-//
-// The other use-case is the specification of constant label pairs in Opts or to
-// create a Desc.
-type Labels map[string]string
-
-// reservedLabelPrefix is a prefix which is not legal in user-supplied
-// label names.
-const reservedLabelPrefix = "__"
-
-var errInconsistentCardinality = errors.New("inconsistent label cardinality")
-
-func validateValuesInLabels(labels Labels, expectedNumberOfValues int) error {
-	if len(labels) != expectedNumberOfValues {
-		return errInconsistentCardinality
-	}
-
-	for name, val := range labels {
-		if !utf8.ValidString(val) {
-			return fmt.Errorf("label %s: value %q is not valid UTF-8", name, val)
-		}
-	}
-
-	return nil
-}
-
-func validateLabelValues(vals []string, expectedNumberOfValues int) error {
-	if len(vals) != expectedNumberOfValues {
-		return errInconsistentCardinality
-	}
-
-	for _, val := range vals {
-		if !utf8.ValidString(val) {
-			return fmt.Errorf("label value %q is not valid UTF-8", val)
-		}
-	}
-
-	return nil
-}
-
-func checkLabelName(l string) bool {
-	return model.LabelName(l).IsValid() && !strings.HasPrefix(l, reservedLabelPrefix)
-}

+ 0 - 50
vendor/github.com/prometheus/client_golang/prometheus/observer.go

@@ -1,50 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-// Observer is the interface that wraps the Observe method, which is used by
-// Histogram and Summary to add observations.
-type Observer interface {
-	Observe(float64)
-}
-
-// The ObserverFunc type is an adapter to allow the use of ordinary
-// functions as Observers. If f is a function with the appropriate
-// signature, ObserverFunc(f) is an Observer that calls f.
-//
-// This adapter is usually used in connection with the Timer type, and there are
-// two general use cases:
-//
-// The most common one is to use a Gauge as the Observer for a Timer.
-// See the "Gauge" Timer example.
-//
-// The more advanced use case is to create a function that dynamically decides
-// which Observer to use for observing the duration. See the "Complex" Timer
-// example.
-type ObserverFunc func(float64)
-
-// Observe calls f(value). It implements Observer.
-func (f ObserverFunc) Observe(value float64) {
-	f(value)
-}
-
-// ObserverVec is an interface implemented by `HistogramVec` and `SummaryVec`.
-type ObserverVec interface {
-	GetMetricWith(Labels) (Observer, error)
-	GetMetricWithLabelValues(lvs ...string) (Observer, error)
-	With(Labels) Observer
-	WithLabelValues(...string) Observer
-
-	Collector
-}

+ 53 - 51
vendor/github.com/prometheus/client_golang/prometheus/process_collector.go

@@ -19,10 +19,10 @@ type processCollector struct {
 	pid             int
 	pid             int
 	collectFn       func(chan<- Metric)
 	collectFn       func(chan<- Metric)
 	pidFn           func() (int, error)
 	pidFn           func() (int, error)
-	cpuTotal        *Desc
-	openFDs, maxFDs *Desc
-	vsize, rss      *Desc
-	startTime       *Desc
+	cpuTotal        Counter
+	openFDs, maxFDs Gauge
+	vsize, rss      Gauge
+	startTime       Gauge
 }
 }
 
 
 // NewProcessCollector returns a collector which exports the current state of
 // NewProcessCollector returns a collector which exports the current state of
@@ -44,45 +44,40 @@ func NewProcessCollectorPIDFn(
 	pidFn func() (int, error),
 	pidFn func() (int, error),
 	namespace string,
 	namespace string,
 ) Collector {
 ) Collector {
-	ns := ""
-	if len(namespace) > 0 {
-		ns = namespace + "_"
-	}
-
 	c := processCollector{
 	c := processCollector{
 		pidFn:     pidFn,
 		pidFn:     pidFn,
 		collectFn: func(chan<- Metric) {},
 		collectFn: func(chan<- Metric) {},
 
 
-		cpuTotal: NewDesc(
-			ns+"process_cpu_seconds_total",
-			"Total user and system CPU time spent in seconds.",
-			nil, nil,
-		),
-		openFDs: NewDesc(
-			ns+"process_open_fds",
-			"Number of open file descriptors.",
-			nil, nil,
-		),
-		maxFDs: NewDesc(
-			ns+"process_max_fds",
-			"Maximum number of open file descriptors.",
-			nil, nil,
-		),
-		vsize: NewDesc(
-			ns+"process_virtual_memory_bytes",
-			"Virtual memory size in bytes.",
-			nil, nil,
-		),
-		rss: NewDesc(
-			ns+"process_resident_memory_bytes",
-			"Resident memory size in bytes.",
-			nil, nil,
-		),
-		startTime: NewDesc(
-			ns+"process_start_time_seconds",
-			"Start time of the process since unix epoch in seconds.",
-			nil, nil,
-		),
+		cpuTotal: NewCounter(CounterOpts{
+			Namespace: namespace,
+			Name:      "process_cpu_seconds_total",
+			Help:      "Total user and system CPU time spent in seconds.",
+		}),
+		openFDs: NewGauge(GaugeOpts{
+			Namespace: namespace,
+			Name:      "process_open_fds",
+			Help:      "Number of open file descriptors.",
+		}),
+		maxFDs: NewGauge(GaugeOpts{
+			Namespace: namespace,
+			Name:      "process_max_fds",
+			Help:      "Maximum number of open file descriptors.",
+		}),
+		vsize: NewGauge(GaugeOpts{
+			Namespace: namespace,
+			Name:      "process_virtual_memory_bytes",
+			Help:      "Virtual memory size in bytes.",
+		}),
+		rss: NewGauge(GaugeOpts{
+			Namespace: namespace,
+			Name:      "process_resident_memory_bytes",
+			Help:      "Resident memory size in bytes.",
+		}),
+		startTime: NewGauge(GaugeOpts{
+			Namespace: namespace,
+			Name:      "process_start_time_seconds",
+			Help:      "Start time of the process since unix epoch in seconds.",
+		}),
 	}
 	}
 
 
 	// Set up process metric collection if supported by the runtime.
 	// Set up process metric collection if supported by the runtime.
@@ -95,12 +90,12 @@ func NewProcessCollectorPIDFn(
 
 
 // Describe returns all descriptions of the collector.
 // Describe returns all descriptions of the collector.
 func (c *processCollector) Describe(ch chan<- *Desc) {
 func (c *processCollector) Describe(ch chan<- *Desc) {
-	ch <- c.cpuTotal
-	ch <- c.openFDs
-	ch <- c.maxFDs
-	ch <- c.vsize
-	ch <- c.rss
-	ch <- c.startTime
+	ch <- c.cpuTotal.Desc()
+	ch <- c.openFDs.Desc()
+	ch <- c.maxFDs.Desc()
+	ch <- c.vsize.Desc()
+	ch <- c.rss.Desc()
+	ch <- c.startTime.Desc()
 }
 }
 
 
 // Collect returns the current state of all metrics of the collector.
 // Collect returns the current state of all metrics of the collector.
@@ -122,19 +117,26 @@ func (c *processCollector) processCollect(ch chan<- Metric) {
 	}
 	}
 
 
 	if stat, err := p.NewStat(); err == nil {
 	if stat, err := p.NewStat(); err == nil {
-		ch <- MustNewConstMetric(c.cpuTotal, CounterValue, stat.CPUTime())
-		ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(stat.VirtualMemory()))
-		ch <- MustNewConstMetric(c.rss, GaugeValue, float64(stat.ResidentMemory()))
+		c.cpuTotal.Set(stat.CPUTime())
+		ch <- c.cpuTotal
+		c.vsize.Set(float64(stat.VirtualMemory()))
+		ch <- c.vsize
+		c.rss.Set(float64(stat.ResidentMemory()))
+		ch <- c.rss
+
 		if startTime, err := stat.StartTime(); err == nil {
 		if startTime, err := stat.StartTime(); err == nil {
-			ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime)
+			c.startTime.Set(startTime)
+			ch <- c.startTime
 		}
 		}
 	}
 	}
 
 
 	if fds, err := p.FileDescriptorsLen(); err == nil {
 	if fds, err := p.FileDescriptorsLen(); err == nil {
-		ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(fds))
+		c.openFDs.Set(float64(fds))
+		ch <- c.openFDs
 	}
 	}
 
 
 	if limits, err := p.NewLimits(); err == nil {
 	if limits, err := p.NewLimits(); err == nil {
-		ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(limits.OpenFiles))
+		c.maxFDs.Set(float64(limits.OpenFiles))
+		ch <- c.maxFDs
 	}
 	}
 }
 }

+ 0 - 199
vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go

@@ -1,199 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package promhttp
-
-import (
-	"bufio"
-	"io"
-	"net"
-	"net/http"
-)
-
-const (
-	closeNotifier = 1 << iota
-	flusher
-	hijacker
-	readerFrom
-	pusher
-)
-
-type delegator interface {
-	http.ResponseWriter
-
-	Status() int
-	Written() int64
-}
-
-type responseWriterDelegator struct {
-	http.ResponseWriter
-
-	handler, method    string
-	status             int
-	written            int64
-	wroteHeader        bool
-	observeWriteHeader func(int)
-}
-
-func (r *responseWriterDelegator) Status() int {
-	return r.status
-}
-
-func (r *responseWriterDelegator) Written() int64 {
-	return r.written
-}
-
-func (r *responseWriterDelegator) WriteHeader(code int) {
-	r.status = code
-	r.wroteHeader = true
-	r.ResponseWriter.WriteHeader(code)
-	if r.observeWriteHeader != nil {
-		r.observeWriteHeader(code)
-	}
-}
-
-func (r *responseWriterDelegator) Write(b []byte) (int, error) {
-	if !r.wroteHeader {
-		r.WriteHeader(http.StatusOK)
-	}
-	n, err := r.ResponseWriter.Write(b)
-	r.written += int64(n)
-	return n, err
-}
-
-type closeNotifierDelegator struct{ *responseWriterDelegator }
-type flusherDelegator struct{ *responseWriterDelegator }
-type hijackerDelegator struct{ *responseWriterDelegator }
-type readerFromDelegator struct{ *responseWriterDelegator }
-
-func (d *closeNotifierDelegator) CloseNotify() <-chan bool {
-	return d.ResponseWriter.(http.CloseNotifier).CloseNotify()
-}
-func (d *flusherDelegator) Flush() {
-	d.ResponseWriter.(http.Flusher).Flush()
-}
-func (d *hijackerDelegator) Hijack() (net.Conn, *bufio.ReadWriter, error) {
-	return d.ResponseWriter.(http.Hijacker).Hijack()
-}
-func (d *readerFromDelegator) ReadFrom(re io.Reader) (int64, error) {
-	if !d.wroteHeader {
-		d.WriteHeader(http.StatusOK)
-	}
-	n, err := d.ResponseWriter.(io.ReaderFrom).ReadFrom(re)
-	d.written += n
-	return n, err
-}
-
-var pickDelegator = make([]func(*responseWriterDelegator) delegator, 32)
-
-func init() {
-	// TODO(beorn7): Code generation would help here.
-	pickDelegator[0] = func(d *responseWriterDelegator) delegator { // 0
-		return d
-	}
-	pickDelegator[closeNotifier] = func(d *responseWriterDelegator) delegator { // 1
-		return closeNotifierDelegator{d}
-	}
-	pickDelegator[flusher] = func(d *responseWriterDelegator) delegator { // 2
-		return flusherDelegator{d}
-	}
-	pickDelegator[flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 3
-		return struct {
-			*responseWriterDelegator
-			http.Flusher
-			http.CloseNotifier
-		}{d, &flusherDelegator{d}, &closeNotifierDelegator{d}}
-	}
-	pickDelegator[hijacker] = func(d *responseWriterDelegator) delegator { // 4
-		return hijackerDelegator{d}
-	}
-	pickDelegator[hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 5
-		return struct {
-			*responseWriterDelegator
-			http.Hijacker
-			http.CloseNotifier
-		}{d, &hijackerDelegator{d}, &closeNotifierDelegator{d}}
-	}
-	pickDelegator[hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 6
-		return struct {
-			*responseWriterDelegator
-			http.Hijacker
-			http.Flusher
-		}{d, &hijackerDelegator{d}, &flusherDelegator{d}}
-	}
-	pickDelegator[hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 7
-		return struct {
-			*responseWriterDelegator
-			http.Hijacker
-			http.Flusher
-			http.CloseNotifier
-		}{d, &hijackerDelegator{d}, &flusherDelegator{d}, &closeNotifierDelegator{d}}
-	}
-	pickDelegator[readerFrom] = func(d *responseWriterDelegator) delegator { // 8
-		return readerFromDelegator{d}
-	}
-	pickDelegator[readerFrom+closeNotifier] = func(d *responseWriterDelegator) delegator { // 9
-		return struct {
-			*responseWriterDelegator
-			io.ReaderFrom
-			http.CloseNotifier
-		}{d, &readerFromDelegator{d}, &closeNotifierDelegator{d}}
-	}
-	pickDelegator[readerFrom+flusher] = func(d *responseWriterDelegator) delegator { // 10
-		return struct {
-			*responseWriterDelegator
-			io.ReaderFrom
-			http.Flusher
-		}{d, &readerFromDelegator{d}, &flusherDelegator{d}}
-	}
-	pickDelegator[readerFrom+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 11
-		return struct {
-			*responseWriterDelegator
-			io.ReaderFrom
-			http.Flusher
-			http.CloseNotifier
-		}{d, &readerFromDelegator{d}, &flusherDelegator{d}, &closeNotifierDelegator{d}}
-	}
-	pickDelegator[readerFrom+hijacker] = func(d *responseWriterDelegator) delegator { // 12
-		return struct {
-			*responseWriterDelegator
-			io.ReaderFrom
-			http.Hijacker
-		}{d, &readerFromDelegator{d}, &hijackerDelegator{d}}
-	}
-	pickDelegator[readerFrom+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 13
-		return struct {
-			*responseWriterDelegator
-			io.ReaderFrom
-			http.Hijacker
-			http.CloseNotifier
-		}{d, &readerFromDelegator{d}, &hijackerDelegator{d}, &closeNotifierDelegator{d}}
-	}
-	pickDelegator[readerFrom+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 14
-		return struct {
-			*responseWriterDelegator
-			io.ReaderFrom
-			http.Hijacker
-			http.Flusher
-		}{d, &readerFromDelegator{d}, &hijackerDelegator{d}, &flusherDelegator{d}}
-	}
-	pickDelegator[readerFrom+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 15
-		return struct {
-			*responseWriterDelegator
-			io.ReaderFrom
-			http.Hijacker
-			http.Flusher
-			http.CloseNotifier
-		}{d, &readerFromDelegator{d}, &hijackerDelegator{d}, &flusherDelegator{d}, &closeNotifierDelegator{d}}
-	}
-}

+ 0 - 181
vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_8.go

@@ -1,181 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build go1.8
-
-package promhttp
-
-import (
-	"io"
-	"net/http"
-)
-
-type pusherDelegator struct{ *responseWriterDelegator }
-
-func (d *pusherDelegator) Push(target string, opts *http.PushOptions) error {
-	return d.ResponseWriter.(http.Pusher).Push(target, opts)
-}
-
-func init() {
-	pickDelegator[pusher] = func(d *responseWriterDelegator) delegator { // 16
-		return pusherDelegator{d}
-	}
-	pickDelegator[pusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 17
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			http.CloseNotifier
-		}{d, &pusherDelegator{d}, &closeNotifierDelegator{d}}
-	}
-	pickDelegator[pusher+flusher] = func(d *responseWriterDelegator) delegator { // 18
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			http.Flusher
-		}{d, &pusherDelegator{d}, &flusherDelegator{d}}
-	}
-	pickDelegator[pusher+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 19
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			http.Flusher
-			http.CloseNotifier
-		}{d, &pusherDelegator{d}, &flusherDelegator{d}, &closeNotifierDelegator{d}}
-	}
-	pickDelegator[pusher+hijacker] = func(d *responseWriterDelegator) delegator { // 20
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			http.Hijacker
-		}{d, &pusherDelegator{d}, &hijackerDelegator{d}}
-	}
-	pickDelegator[pusher+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 21
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			http.Hijacker
-			http.CloseNotifier
-		}{d, &pusherDelegator{d}, &hijackerDelegator{d}, &closeNotifierDelegator{d}}
-	}
-	pickDelegator[pusher+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 22
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			http.Hijacker
-			http.Flusher
-		}{d, &pusherDelegator{d}, &hijackerDelegator{d}, &flusherDelegator{d}}
-	}
-	pickDelegator[pusher+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { //23
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			http.Hijacker
-			http.Flusher
-			http.CloseNotifier
-		}{d, &pusherDelegator{d}, &hijackerDelegator{d}, &flusherDelegator{d}, &closeNotifierDelegator{d}}
-	}
-	pickDelegator[pusher+readerFrom] = func(d *responseWriterDelegator) delegator { // 24
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			io.ReaderFrom
-		}{d, &pusherDelegator{d}, &readerFromDelegator{d}}
-	}
-	pickDelegator[pusher+readerFrom+closeNotifier] = func(d *responseWriterDelegator) delegator { // 25
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			io.ReaderFrom
-			http.CloseNotifier
-		}{d, &pusherDelegator{d}, &readerFromDelegator{d}, &closeNotifierDelegator{d}}
-	}
-	pickDelegator[pusher+readerFrom+flusher] = func(d *responseWriterDelegator) delegator { // 26
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			io.ReaderFrom
-			http.Flusher
-		}{d, &pusherDelegator{d}, &readerFromDelegator{d}, &flusherDelegator{d}}
-	}
-	pickDelegator[pusher+readerFrom+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 27
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			io.ReaderFrom
-			http.Flusher
-			http.CloseNotifier
-		}{d, &pusherDelegator{d}, &readerFromDelegator{d}, &flusherDelegator{d}, &closeNotifierDelegator{d}}
-	}
-	pickDelegator[pusher+readerFrom+hijacker] = func(d *responseWriterDelegator) delegator { // 28
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			io.ReaderFrom
-			http.Hijacker
-		}{d, &pusherDelegator{d}, &readerFromDelegator{d}, &hijackerDelegator{d}}
-	}
-	pickDelegator[pusher+readerFrom+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 29
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			io.ReaderFrom
-			http.Hijacker
-			http.CloseNotifier
-		}{d, &pusherDelegator{d}, &readerFromDelegator{d}, &hijackerDelegator{d}, &closeNotifierDelegator{d}}
-	}
-	pickDelegator[pusher+readerFrom+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 30
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			io.ReaderFrom
-			http.Hijacker
-			http.Flusher
-		}{d, &pusherDelegator{d}, &readerFromDelegator{d}, &hijackerDelegator{d}, &flusherDelegator{d}}
-	}
-	pickDelegator[pusher+readerFrom+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 31
-		return struct {
-			*responseWriterDelegator
-			http.Pusher
-			io.ReaderFrom
-			http.Hijacker
-			http.Flusher
-			http.CloseNotifier
-		}{d, &pusherDelegator{d}, &readerFromDelegator{d}, &hijackerDelegator{d}, &flusherDelegator{d}, &closeNotifierDelegator{d}}
-	}
-}
-
-func newDelegator(w http.ResponseWriter, observeWriteHeaderFunc func(int)) delegator {
-	d := &responseWriterDelegator{
-		ResponseWriter:     w,
-		observeWriteHeader: observeWriteHeaderFunc,
-	}
-
-	id := 0
-	if _, ok := w.(http.CloseNotifier); ok {
-		id += closeNotifier
-	}
-	if _, ok := w.(http.Flusher); ok {
-		id += flusher
-	}
-	if _, ok := w.(http.Hijacker); ok {
-		id += hijacker
-	}
-	if _, ok := w.(io.ReaderFrom); ok {
-		id += readerFrom
-	}
-	if _, ok := w.(http.Pusher); ok {
-		id += pusher
-	}
-
-	return pickDelegator[id](d)
-}

+ 0 - 44
vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_pre_1_8.go

@@ -1,44 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build !go1.8
-
-package promhttp
-
-import (
-	"io"
-	"net/http"
-)
-
-func newDelegator(w http.ResponseWriter, observeWriteHeaderFunc func(int)) delegator {
-	d := &responseWriterDelegator{
-		ResponseWriter:     w,
-		observeWriteHeader: observeWriteHeaderFunc,
-	}
-
-	id := 0
-	if _, ok := w.(http.CloseNotifier); ok {
-		id += closeNotifier
-	}
-	if _, ok := w.(http.Flusher); ok {
-		id += flusher
-	}
-	if _, ok := w.(http.Hijacker); ok {
-		id += hijacker
-	}
-	if _, ok := w.(io.ReaderFrom); ok {
-		id += readerFrom
-	}
-
-	return pickDelegator[id](d)
-}

+ 14 - 17
vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go

@@ -11,24 +11,21 @@
 // See the License for the specific language governing permissions and
 // See the License for the specific language governing permissions and
 // limitations under the License.
 // limitations under the License.
 
 
-// Package promhttp provides tooling around HTTP servers and clients.
+// Copyright (c) 2013, The Prometheus Authors
+// All rights reserved.
 //
 //
-// First, the package allows the creation of http.Handler instances to expose
-// Prometheus metrics via HTTP. promhttp.Handler acts on the
-// prometheus.DefaultGatherer. With HandlerFor, you can create a handler for a
-// custom registry or anything that implements the Gatherer interface. It also
-// allows the creation of handlers that act differently on errors or allow to
-// log errors.
-//
-// Second, the package provides tooling to instrument instances of http.Handler
-// via middleware. Middleware wrappers follow the naming scheme
-// InstrumentHandlerX, where X describes the intended use of the middleware.
-// See each function's doc comment for specific details.
+// Use of this source code is governed by a BSD-style license that can be found
+// in the LICENSE file.
+
+// Package promhttp contains functions to create http.Handler instances to
+// expose Prometheus metrics via HTTP. In later versions of this package, it
+// will also contain tooling to instrument instances of http.Handler and
+// http.RoundTripper.
 //
 //
-// Finally, the package allows for an http.RoundTripper to be instrumented via
-// middleware. Middleware wrappers follow the naming scheme
-// InstrumentRoundTripperX, where X describes the intended use of the
-// middleware. See each function's doc comment for specific details.
+// promhttp.Handler acts on the prometheus.DefaultGatherer. With HandlerFor,
+// you can create a handler for a custom registry or anything that implements
+// the Gatherer interface. It also allows to create handlers that act
+// differently on errors or allow to log errors.
 package promhttp
 package promhttp
 
 
 import (
 import (
@@ -128,7 +125,7 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
 			closer.Close()
 			closer.Close()
 		}
 		}
 		if lastErr != nil && buf.Len() == 0 {
 		if lastErr != nil && buf.Len() == 0 {
-			http.Error(w, "No metrics encoded, last error:\n\n"+lastErr.Error(), http.StatusInternalServerError)
+			http.Error(w, "No metrics encoded, last error:\n\n"+err.Error(), http.StatusInternalServerError)
 			return
 			return
 		}
 		}
 		header := w.Header()
 		header := w.Header()

+ 0 - 98
vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go

@@ -1,98 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package promhttp
-
-import (
-	"net/http"
-	"time"
-
-	"github.com/prometheus/client_golang/prometheus"
-)
-
-// The RoundTripperFunc type is an adapter to allow the use of ordinary
-// functions as RoundTrippers. If f is a function with the appropriate
-// signature, RountTripperFunc(f) is a RoundTripper that calls f.
-type RoundTripperFunc func(req *http.Request) (*http.Response, error)
-
-// RoundTrip implements the RoundTripper interface.
-func (rt RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) {
-	return rt(r)
-}
-
-// InstrumentRoundTripperInFlight is a middleware that wraps the provided
-// http.RoundTripper. It sets the provided prometheus.Gauge to the number of
-// requests currently handled by the wrapped http.RoundTripper.
-//
-// See the example for ExampleInstrumentRoundTripperDuration for example usage.
-func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripper) RoundTripperFunc {
-	return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
-		gauge.Inc()
-		defer gauge.Dec()
-		return next.RoundTrip(r)
-	})
-}
-
-// InstrumentRoundTripperCounter is a middleware that wraps the provided
-// http.RoundTripper to observe the request result with the provided CounterVec.
-// The CounterVec must have zero, one, or two labels. The only allowed label
-// names are "code" and "method". The function panics if any other instance
-// labels are provided. Partitioning of the CounterVec happens by HTTP status
-// code and/or HTTP method if the respective instance label names are present
-// in the CounterVec. For unpartitioned counting, use a CounterVec with
-// zero labels.
-//
-// If the wrapped RoundTripper panics or returns a non-nil error, the Counter
-// is not incremented.
-//
-// See the example for ExampleInstrumentRoundTripperDuration for example usage.
-func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.RoundTripper) RoundTripperFunc {
-	code, method := checkLabels(counter)
-
-	return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
-		resp, err := next.RoundTrip(r)
-		if err == nil {
-			counter.With(labels(code, method, r.Method, resp.StatusCode)).Inc()
-		}
-		return resp, err
-	})
-}
-
-// InstrumentRoundTripperDuration is a middleware that wraps the provided
-// http.RoundTripper to observe the request duration with the provided ObserverVec.
-// The ObserverVec must have zero, one, or two labels. The only allowed label
-// names are "code" and "method". The function panics if any other instance
-// labels are provided. The Observe method of the Observer in the ObserverVec
-// is called with the request duration in seconds. Partitioning happens by HTTP
-// status code and/or HTTP method if the respective instance label names are
-// present in the ObserverVec. For unpartitioned observations, use an
-// ObserverVec with zero labels. Note that partitioning of Histograms is
-// expensive and should be used judiciously.
-//
-// If the wrapped RoundTripper panics or returns a non-nil error, no values are
-// reported.
-//
-// Note that this method is only guaranteed to never observe negative durations
-// if used with Go1.9+.
-func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundTripper) RoundTripperFunc {
-	code, method := checkLabels(obs)
-
-	return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
-		start := time.Now()
-		resp, err := next.RoundTrip(r)
-		if err == nil {
-			obs.With(labels(code, method, r.Method, resp.StatusCode)).Observe(time.Since(start).Seconds())
-		}
-		return resp, err
-	})
-}

+ 0 - 144
vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client_1_8.go

@@ -1,144 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build go1.8
-
-package promhttp
-
-import (
-	"context"
-	"crypto/tls"
-	"net/http"
-	"net/http/httptrace"
-	"time"
-)
-
-// InstrumentTrace is used to offer flexibility in instrumenting the available
-// httptrace.ClientTrace hook functions. Each function is passed a float64
-// representing the time in seconds since the start of the http request. A user
-// may choose to use separately buckets Histograms, or implement custom
-// instance labels on a per function basis.
-type InstrumentTrace struct {
-	GotConn              func(float64)
-	PutIdleConn          func(float64)
-	GotFirstResponseByte func(float64)
-	Got100Continue       func(float64)
-	DNSStart             func(float64)
-	DNSDone              func(float64)
-	ConnectStart         func(float64)
-	ConnectDone          func(float64)
-	TLSHandshakeStart    func(float64)
-	TLSHandshakeDone     func(float64)
-	WroteHeaders         func(float64)
-	Wait100Continue      func(float64)
-	WroteRequest         func(float64)
-}
-
-// InstrumentRoundTripperTrace is a middleware that wraps the provided
-// RoundTripper and reports times to hook functions provided in the
-// InstrumentTrace struct. Hook functions that are not present in the provided
-// InstrumentTrace struct are ignored. Times reported to the hook functions are
-// time since the start of the request. Only with Go1.9+, those times are
-// guaranteed to never be negative. (Earlier Go versions are not using a
-// monotonic clock.) Note that partitioning of Histograms is expensive and
-// should be used judiciously.
-//
-// For hook functions that receive an error as an argument, no observations are
-// made in the event of a non-nil error value.
-//
-// See the example for ExampleInstrumentRoundTripperDuration for example usage.
-func InstrumentRoundTripperTrace(it *InstrumentTrace, next http.RoundTripper) RoundTripperFunc {
-	return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
-		start := time.Now()
-
-		trace := &httptrace.ClientTrace{
-			GotConn: func(_ httptrace.GotConnInfo) {
-				if it.GotConn != nil {
-					it.GotConn(time.Since(start).Seconds())
-				}
-			},
-			PutIdleConn: func(err error) {
-				if err != nil {
-					return
-				}
-				if it.PutIdleConn != nil {
-					it.PutIdleConn(time.Since(start).Seconds())
-				}
-			},
-			DNSStart: func(_ httptrace.DNSStartInfo) {
-				if it.DNSStart != nil {
-					it.DNSStart(time.Since(start).Seconds())
-				}
-			},
-			DNSDone: func(_ httptrace.DNSDoneInfo) {
-				if it.DNSStart != nil {
-					it.DNSStart(time.Since(start).Seconds())
-				}
-			},
-			ConnectStart: func(_, _ string) {
-				if it.ConnectStart != nil {
-					it.ConnectStart(time.Since(start).Seconds())
-				}
-			},
-			ConnectDone: func(_, _ string, err error) {
-				if err != nil {
-					return
-				}
-				if it.ConnectDone != nil {
-					it.ConnectDone(time.Since(start).Seconds())
-				}
-			},
-			GotFirstResponseByte: func() {
-				if it.GotFirstResponseByte != nil {
-					it.GotFirstResponseByte(time.Since(start).Seconds())
-				}
-			},
-			Got100Continue: func() {
-				if it.Got100Continue != nil {
-					it.Got100Continue(time.Since(start).Seconds())
-				}
-			},
-			TLSHandshakeStart: func() {
-				if it.TLSHandshakeStart != nil {
-					it.TLSHandshakeStart(time.Since(start).Seconds())
-				}
-			},
-			TLSHandshakeDone: func(_ tls.ConnectionState, err error) {
-				if err != nil {
-					return
-				}
-				if it.TLSHandshakeDone != nil {
-					it.TLSHandshakeDone(time.Since(start).Seconds())
-				}
-			},
-			WroteHeaders: func() {
-				if it.WroteHeaders != nil {
-					it.WroteHeaders(time.Since(start).Seconds())
-				}
-			},
-			Wait100Continue: func() {
-				if it.Wait100Continue != nil {
-					it.Wait100Continue(time.Since(start).Seconds())
-				}
-			},
-			WroteRequest: func(_ httptrace.WroteRequestInfo) {
-				if it.WroteRequest != nil {
-					it.WroteRequest(time.Since(start).Seconds())
-				}
-			},
-		}
-		r = r.WithContext(httptrace.WithClientTrace(context.Background(), trace))
-
-		return next.RoundTrip(r)
-	})
-}

+ 0 - 440
vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go

@@ -1,440 +0,0 @@
-// Copyright 2017 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package promhttp
-
-import (
-	"net/http"
-	"strconv"
-	"strings"
-	"time"
-
-	dto "github.com/prometheus/client_model/go"
-
-	"github.com/prometheus/client_golang/prometheus"
-)
-
-// magicString is used for the hacky label test in checkLabels. Remove once fixed.
-const magicString = "zZgWfBxLqvG8kc8IMv3POi2Bb0tZI3vAnBx+gBaFi9FyPzB/CzKUer1yufDa"
-
-// InstrumentHandlerInFlight is a middleware that wraps the provided
-// http.Handler. It sets the provided prometheus.Gauge to the number of
-// requests currently handled by the wrapped http.Handler.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handler {
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		g.Inc()
-		defer g.Dec()
-		next.ServeHTTP(w, r)
-	})
-}
-
-// InstrumentHandlerDuration is a middleware that wraps the provided
-// http.Handler to observe the request duration with the provided ObserverVec.
-// The ObserverVec must have zero, one, or two labels. The only allowed label
-// names are "code" and "method". The function panics if any other instance
-// labels are provided. The Observe method of the Observer in the ObserverVec
-// is called with the request duration in seconds. Partitioning happens by HTTP
-// status code and/or HTTP method if the respective instance label names are
-// present in the ObserverVec. For unpartitioned observations, use an
-// ObserverVec with zero labels. Note that partitioning of Histograms is
-// expensive and should be used judiciously.
-//
-// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
-//
-// If the wrapped Handler panics, no values are reported.
-//
-// Note that this method is only guaranteed to never observe negative durations
-// if used with Go1.9+.
-func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
-	code, method := checkLabels(obs)
-
-	if code {
-		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-			now := time.Now()
-			d := newDelegator(w, nil)
-			next.ServeHTTP(d, r)
-
-			obs.With(labels(code, method, r.Method, d.Status())).Observe(time.Since(now).Seconds())
-		})
-	}
-
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		now := time.Now()
-		next.ServeHTTP(w, r)
-		obs.With(labels(code, method, r.Method, 0)).Observe(time.Since(now).Seconds())
-	})
-}
-
-// InstrumentHandlerCounter is a middleware that wraps the provided
-// http.Handler to observe the request result with the provided CounterVec.
-// The CounterVec must have zero, one, or two labels. The only allowed label
-// names are "code" and "method". The function panics if any other instance
-// labels are provided. Partitioning of the CounterVec happens by HTTP status
-// code and/or HTTP method if the respective instance label names are present
-// in the CounterVec. For unpartitioned counting, use a CounterVec with
-// zero labels.
-//
-// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
-//
-// If the wrapped Handler panics, the Counter is not incremented.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler) http.HandlerFunc {
-	code, method := checkLabels(counter)
-
-	if code {
-		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-			d := newDelegator(w, nil)
-			next.ServeHTTP(d, r)
-			counter.With(labels(code, method, r.Method, d.Status())).Inc()
-		})
-	}
-
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		next.ServeHTTP(w, r)
-		counter.With(labels(code, method, r.Method, 0)).Inc()
-	})
-}
-
-// InstrumentHandlerTimeToWriteHeader is a middleware that wraps the provided
-// http.Handler to observe with the provided ObserverVec the request duration
-// until the response headers are written. The ObserverVec must have zero, one,
-// or two labels. The only allowed label names are "code" and "method". The
-// function panics if any other instance labels are provided. The Observe
-// method of the Observer in the ObserverVec is called with the request
-// duration in seconds. Partitioning happens by HTTP status code and/or HTTP
-// method if the respective instance label names are present in the
-// ObserverVec. For unpartitioned observations, use an ObserverVec with zero
-// labels. Note that partitioning of Histograms is expensive and should be used
-// judiciously.
-//
-// If the wrapped Handler panics before calling WriteHeader, no value is
-// reported.
-//
-// Note that this method is only guaranteed to never observe negative durations
-// if used with Go1.9+.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
-	code, method := checkLabels(obs)
-
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		now := time.Now()
-		d := newDelegator(w, func(status int) {
-			obs.With(labels(code, method, r.Method, status)).Observe(time.Since(now).Seconds())
-		})
-		next.ServeHTTP(d, r)
-	})
-}
-
-// InstrumentHandlerRequestSize is a middleware that wraps the provided
-// http.Handler to observe the request size with the provided ObserverVec.
-// The ObserverVec must have zero, one, or two labels. The only allowed label
-// names are "code" and "method". The function panics if any other instance
-// labels are provided. The Observe method of the Observer in the ObserverVec
-// is called with the request size in bytes. Partitioning happens by HTTP
-// status code and/or HTTP method if the respective instance label names are
-// present in the ObserverVec. For unpartitioned observations, use an
-// ObserverVec with zero labels. Note that partitioning of Histograms is
-// expensive and should be used judiciously.
-//
-// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
-//
-// If the wrapped Handler panics, no values are reported.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
-	code, method := checkLabels(obs)
-
-	if code {
-		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-			d := newDelegator(w, nil)
-			next.ServeHTTP(d, r)
-			size := computeApproximateRequestSize(r)
-			obs.With(labels(code, method, r.Method, d.Status())).Observe(float64(size))
-		})
-	}
-
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		next.ServeHTTP(w, r)
-		size := computeApproximateRequestSize(r)
-		obs.With(labels(code, method, r.Method, 0)).Observe(float64(size))
-	})
-}
-
-// InstrumentHandlerResponseSize is a middleware that wraps the provided
-// http.Handler to observe the response size with the provided ObserverVec.
-// The ObserverVec must have zero, one, or two labels. The only allowed label
-// names are "code" and "method". The function panics if any other instance
-// labels are provided. The Observe method of the Observer in the ObserverVec
-// is called with the response size in bytes. Partitioning happens by HTTP
-// status code and/or HTTP method if the respective instance label names are
-// present in the ObserverVec. For unpartitioned observations, use an
-// ObserverVec with zero labels. Note that partitioning of Histograms is
-// expensive and should be used judiciously.
-//
-// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
-//
-// If the wrapped Handler panics, no values are reported.
-//
-// See the example for InstrumentHandlerDuration for example usage.
-func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler) http.Handler {
-	code, method := checkLabels(obs)
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		d := newDelegator(w, nil)
-		next.ServeHTTP(d, r)
-		obs.With(labels(code, method, r.Method, d.Status())).Observe(float64(d.Written()))
-	})
-}
-
-func checkLabels(c prometheus.Collector) (code bool, method bool) {
-	// TODO(beorn7): Remove this hacky way to check for instance labels
-	// once Descriptors can have their dimensionality queried.
-	var (
-		desc *prometheus.Desc
-		pm   dto.Metric
-	)
-
-	descc := make(chan *prometheus.Desc, 1)
-	c.Describe(descc)
-
-	select {
-	case desc = <-descc:
-	default:
-		panic("no description provided by collector")
-	}
-	select {
-	case <-descc:
-		panic("more than one description provided by collector")
-	default:
-	}
-
-	close(descc)
-
-	if _, err := prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0); err == nil {
-		return
-	}
-	if m, err := prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0, magicString); err == nil {
-		if err := m.Write(&pm); err != nil {
-			panic("error checking metric for labels")
-		}
-		for _, label := range pm.Label {
-			name, value := label.GetName(), label.GetValue()
-			if value != magicString {
-				continue
-			}
-			switch name {
-			case "code":
-				code = true
-			case "method":
-				method = true
-			default:
-				panic("metric partitioned with non-supported labels")
-			}
-			return
-		}
-		panic("previously set label not found – this must never happen")
-	}
-	if m, err := prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0, magicString, magicString); err == nil {
-		if err := m.Write(&pm); err != nil {
-			panic("error checking metric for labels")
-		}
-		for _, label := range pm.Label {
-			name, value := label.GetName(), label.GetValue()
-			if value != magicString {
-				continue
-			}
-			if name == "code" || name == "method" {
-				continue
-			}
-			panic("metric partitioned with non-supported labels")
-		}
-		code = true
-		method = true
-		return
-	}
-	panic("metric partitioned with non-supported labels")
-}
-
-// emptyLabels is a one-time allocation for non-partitioned metrics to avoid
-// unnecessary allocations on each request.
-var emptyLabels = prometheus.Labels{}
-
-func labels(code, method bool, reqMethod string, status int) prometheus.Labels {
-	if !(code || method) {
-		return emptyLabels
-	}
-	labels := prometheus.Labels{}
-
-	if code {
-		labels["code"] = sanitizeCode(status)
-	}
-	if method {
-		labels["method"] = sanitizeMethod(reqMethod)
-	}
-
-	return labels
-}
-
-func computeApproximateRequestSize(r *http.Request) int {
-	s := 0
-	if r.URL != nil {
-		s += len(r.URL.String())
-	}
-
-	s += len(r.Method)
-	s += len(r.Proto)
-	for name, values := range r.Header {
-		s += len(name)
-		for _, value := range values {
-			s += len(value)
-		}
-	}
-	s += len(r.Host)
-
-	// N.B. r.Form and r.MultipartForm are assumed to be included in r.URL.
-
-	if r.ContentLength != -1 {
-		s += int(r.ContentLength)
-	}
-	return s
-}
-
-func sanitizeMethod(m string) string {
-	switch m {
-	case "GET", "get":
-		return "get"
-	case "PUT", "put":
-		return "put"
-	case "HEAD", "head":
-		return "head"
-	case "POST", "post":
-		return "post"
-	case "DELETE", "delete":
-		return "delete"
-	case "CONNECT", "connect":
-		return "connect"
-	case "OPTIONS", "options":
-		return "options"
-	case "NOTIFY", "notify":
-		return "notify"
-	default:
-		return strings.ToLower(m)
-	}
-}
-
-// If the wrapped http.Handler has not set a status code, i.e. the value is
-// currently 0, santizeCode will return 200, for consistency with behavior in
-// the stdlib.
-func sanitizeCode(s int) string {
-	switch s {
-	case 100:
-		return "100"
-	case 101:
-		return "101"
-
-	case 200, 0:
-		return "200"
-	case 201:
-		return "201"
-	case 202:
-		return "202"
-	case 203:
-		return "203"
-	case 204:
-		return "204"
-	case 205:
-		return "205"
-	case 206:
-		return "206"
-
-	case 300:
-		return "300"
-	case 301:
-		return "301"
-	case 302:
-		return "302"
-	case 304:
-		return "304"
-	case 305:
-		return "305"
-	case 307:
-		return "307"
-
-	case 400:
-		return "400"
-	case 401:
-		return "401"
-	case 402:
-		return "402"
-	case 403:
-		return "403"
-	case 404:
-		return "404"
-	case 405:
-		return "405"
-	case 406:
-		return "406"
-	case 407:
-		return "407"
-	case 408:
-		return "408"
-	case 409:
-		return "409"
-	case 410:
-		return "410"
-	case 411:
-		return "411"
-	case 412:
-		return "412"
-	case 413:
-		return "413"
-	case 414:
-		return "414"
-	case 415:
-		return "415"
-	case 416:
-		return "416"
-	case 417:
-		return "417"
-	case 418:
-		return "418"
-
-	case 500:
-		return "500"
-	case 501:
-		return "501"
-	case 502:
-		return "502"
-	case 503:
-		return "503"
-	case 504:
-		return "504"
-	case 505:
-		return "505"
-
-	case 428:
-		return "428"
-	case 429:
-		return "429"
-	case 431:
-		return "431"
-	case 511:
-		return "511"
-
-	default:
-		return strconv.Itoa(s)
-	}
-}

+ 56 - 12
vendor/github.com/prometheus/client_golang/prometheus/registry.go

@@ -20,7 +20,6 @@ import (
 	"os"
 	"os"
 	"sort"
 	"sort"
 	"sync"
 	"sync"
-	"unicode/utf8"
 
 
 	"github.com/golang/protobuf/proto"
 	"github.com/golang/protobuf/proto"
 
 
@@ -81,7 +80,7 @@ func NewPedanticRegistry() *Registry {
 
 
 // Registerer is the interface for the part of a registry in charge of
 // Registerer is the interface for the part of a registry in charge of
 // registering and unregistering. Users of custom registries should use
 // registering and unregistering. Users of custom registries should use
-// Registerer as type for registration purposes (rather than the Registry type
+// Registerer as type for registration purposes (rather then the Registry type
 // directly). In that way, they are free to use custom Registerer implementation
 // directly). In that way, they are free to use custom Registerer implementation
 // (e.g. for testing purposes).
 // (e.g. for testing purposes).
 type Registerer interface {
 type Registerer interface {
@@ -153,6 +152,38 @@ func MustRegister(cs ...Collector) {
 	DefaultRegisterer.MustRegister(cs...)
 	DefaultRegisterer.MustRegister(cs...)
 }
 }
 
 
+// RegisterOrGet registers the provided Collector with the DefaultRegisterer and
+// returns the Collector, unless an equal Collector was registered before, in
+// which case that Collector is returned.
+//
+// Deprecated: RegisterOrGet is merely a convenience function for the
+// implementation as described in the documentation for
+// AlreadyRegisteredError. As the use case is relatively rare, this function
+// will be removed in a future version of this package to clean up the
+// namespace.
+func RegisterOrGet(c Collector) (Collector, error) {
+	if err := Register(c); err != nil {
+		if are, ok := err.(AlreadyRegisteredError); ok {
+			return are.ExistingCollector, nil
+		}
+		return nil, err
+	}
+	return c, nil
+}
+
+// MustRegisterOrGet behaves like RegisterOrGet but panics instead of returning
+// an error.
+//
+// Deprecated: This is deprecated for the same reason RegisterOrGet is. See
+// there for details.
+func MustRegisterOrGet(c Collector) Collector {
+	c, err := RegisterOrGet(c)
+	if err != nil {
+		panic(err)
+	}
+	return c
+}
+
 // Unregister removes the registration of the provided Collector from the
 // Unregister removes the registration of the provided Collector from the
 // DefaultRegisterer.
 // DefaultRegisterer.
 //
 //
@@ -170,6 +201,25 @@ func (gf GathererFunc) Gather() ([]*dto.MetricFamily, error) {
 	return gf()
 	return gf()
 }
 }
 
 
+// SetMetricFamilyInjectionHook replaces the DefaultGatherer with one that
+// gathers from the previous DefaultGatherers but then merges the MetricFamily
+// protobufs returned from the provided hook function with the MetricFamily
+// protobufs returned from the original DefaultGatherer.
+//
+// Deprecated: This function manipulates the DefaultGatherer variable. Consider
+// the implications, i.e. don't do this concurrently with any uses of the
+// DefaultGatherer. In the rare cases where you need to inject MetricFamily
+// protobufs directly, it is recommended to use a custom Registry and combine it
+// with a custom Gatherer using the Gatherers type (see
+// there). SetMetricFamilyInjectionHook only exists for compatibility reasons
+// with previous versions of this package.
+func SetMetricFamilyInjectionHook(hook func() []*dto.MetricFamily) {
+	DefaultGatherer = Gatherers{
+		DefaultGatherer,
+		GathererFunc(func() ([]*dto.MetricFamily, error) { return hook(), nil }),
+	}
+}
+
 // AlreadyRegisteredError is returned by the Register method if the Collector to
 // AlreadyRegisteredError is returned by the Register method if the Collector to
 // be registered has already been registered before, or a different Collector
 // be registered has already been registered before, or a different Collector
 // that collects the same metrics has been registered before. Registration fails
 // that collects the same metrics has been registered before. Registration fails
@@ -244,7 +294,7 @@ func (r *Registry) Register(c Collector) error {
 	}()
 	}()
 	r.mtx.Lock()
 	r.mtx.Lock()
 	defer r.mtx.Unlock()
 	defer r.mtx.Unlock()
-	// Conduct various tests...
+	// Coduct various tests...
 	for desc := range descChan {
 	for desc := range descChan {
 
 
 		// Is the descriptor valid at all?
 		// Is the descriptor valid at all?
@@ -397,7 +447,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
 
 
 	// Drain metricChan in case of premature return.
 	// Drain metricChan in case of premature return.
 	defer func() {
 	defer func() {
-		for range metricChan {
+		for _ = range metricChan {
 		}
 		}
 	}()
 	}()
 
 
@@ -633,7 +683,7 @@ func (s metricSorter) Less(i, j int) bool {
 	return s[i].GetTimestampMs() < s[j].GetTimestampMs()
 	return s[i].GetTimestampMs() < s[j].GetTimestampMs()
 }
 }
 
 
-// normalizeMetricFamilies returns a MetricFamily slice with empty
+// normalizeMetricFamilies returns a MetricFamily slice whith empty
 // MetricFamilies pruned and the remaining MetricFamilies sorted by name within
 // MetricFamilies pruned and the remaining MetricFamilies sorted by name within
 // the slice, with the contained Metrics sorted within each MetricFamily.
 // the slice, with the contained Metrics sorted within each MetricFamily.
 func normalizeMetricFamilies(metricFamiliesByName map[string]*dto.MetricFamily) []*dto.MetricFamily {
 func normalizeMetricFamilies(metricFamiliesByName map[string]*dto.MetricFamily) []*dto.MetricFamily {
@@ -656,7 +706,7 @@ func normalizeMetricFamilies(metricFamiliesByName map[string]*dto.MetricFamily)
 
 
 // checkMetricConsistency checks if the provided Metric is consistent with the
 // checkMetricConsistency checks if the provided Metric is consistent with the
 // provided MetricFamily. It also hashed the Metric labels and the MetricFamily
 // provided MetricFamily. It also hashed the Metric labels and the MetricFamily
-// name. If the resulting hash is already in the provided metricHashes, an error
+// name. If the resulting hash is alread in the provided metricHashes, an error
 // is returned. If not, it is added to metricHashes. The provided dimHashes maps
 // is returned. If not, it is added to metricHashes. The provided dimHashes maps
 // MetricFamily names to their dimHash (hashed sorted label names). If dimHashes
 // MetricFamily names to their dimHash (hashed sorted label names). If dimHashes
 // doesn't yet contain a hash for the provided MetricFamily, it is
 // doesn't yet contain a hash for the provided MetricFamily, it is
@@ -680,12 +730,6 @@ func checkMetricConsistency(
 		)
 		)
 	}
 	}
 
 
-	for _, labelPair := range dtoMetric.GetLabel() {
-		if !utf8.ValidString(*labelPair.Value) {
-			return fmt.Errorf("collected metric's label %s is not utf8: %#v", *labelPair.Name, *labelPair.Value)
-		}
-	}
-
 	// Is the metric unique (i.e. no other metric with the same name and the same label values)?
 	// Is the metric unique (i.e. no other metric with the same name and the same label values)?
 	h := hashNew()
 	h := hashNew()
 	h = hashAdd(h, metricFamily.GetName())
 	h = hashAdd(h, metricFamily.GetName())

+ 29 - 72
vendor/github.com/prometheus/client_golang/prometheus/summary.go

@@ -36,10 +36,7 @@ const quantileLabel = "quantile"
 //
 //
 // A typical use-case is the observation of request latencies. By default, a
 // A typical use-case is the observation of request latencies. By default, a
 // Summary provides the median, the 90th and the 99th percentile of the latency
 // Summary provides the median, the 90th and the 99th percentile of the latency
-// as rank estimations. However, the default behavior will change in the
-// upcoming v0.10 of the library. There will be no rank estiamtions at all by
-// default. For a sane transition, it is recommended to set the desired rank
-// estimations explicitly.
+// as rank estimations.
 //
 //
 // Note that the rank estimations cannot be aggregated in a meaningful way with
 // Note that the rank estimations cannot be aggregated in a meaningful way with
 // the Prometheus query language (i.e. you cannot average or add them). If you
 // the Prometheus query language (i.e. you cannot average or add them). If you
@@ -57,9 +54,6 @@ type Summary interface {
 }
 }
 
 
 // DefObjectives are the default Summary quantile values.
 // DefObjectives are the default Summary quantile values.
-//
-// Deprecated: DefObjectives will not be used as the default objectives in
-// v0.10 of the library. The default Summary will have no quantiles then.
 var (
 var (
 	DefObjectives = map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}
 	DefObjectives = map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}
 
 
@@ -81,10 +75,8 @@ const (
 )
 )
 
 
 // SummaryOpts bundles the options for creating a Summary metric. It is
 // SummaryOpts bundles the options for creating a Summary metric. It is
-// mandatory to set Name and Help to a non-empty string. While all other fields
-// are optional and can safely be left at their zero value, it is recommended to
-// explicitly set the Objectives field to the desired value as the default value
-// will change in the upcoming v0.10 of the library.
+// mandatory to set Name and Help to a non-empty string. All other fields are
+// optional and can safely be left at their zero value.
 type SummaryOpts struct {
 type SummaryOpts struct {
 	// Namespace, Subsystem, and Name are components of the fully-qualified
 	// Namespace, Subsystem, and Name are components of the fully-qualified
 	// name of the Summary (created by joining these components with
 	// name of the Summary (created by joining these components with
@@ -121,15 +113,9 @@ type SummaryOpts struct {
 	ConstLabels Labels
 	ConstLabels Labels
 
 
 	// Objectives defines the quantile rank estimates with their respective
 	// Objectives defines the quantile rank estimates with their respective
-	// absolute error. If Objectives[q] = e, then the value reported for q
-	// will be the φ-quantile value for some φ between q-e and q+e.  The
-	// default value is DefObjectives. It is used if Objectives is left at
-	// its zero value (i.e. nil). To create a Summary without Objectives,
-	// set it to an empty map (i.e. map[float64]float64{}).
-	//
-	// Deprecated: Note that the current value of DefObjectives is
-	// deprecated. It will be replaced by an empty map in v0.10 of the
-	// library. Please explicitly set Objectives to the desired value.
+	// absolute error. If Objectives[q] = e, then the value reported
+	// for q will be the φ-quantile value for some φ between q-e and q+e.
+	// The default value is DefObjectives.
 	Objectives map[float64]float64
 	Objectives map[float64]float64
 
 
 	// MaxAge defines the duration for which an observation stays relevant
 	// MaxAge defines the duration for which an observation stays relevant
@@ -197,7 +183,7 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {
 		}
 		}
 	}
 	}
 
 
-	if opts.Objectives == nil {
+	if len(opts.Objectives) == 0 {
 		opts.Objectives = DefObjectives
 		opts.Objectives = DefObjectives
 	}
 	}
 
 
@@ -404,11 +390,12 @@ func (s quantSort) Less(i, j int) bool {
 // (e.g. HTTP request latencies, partitioned by status code and method). Create
 // (e.g. HTTP request latencies, partitioned by status code and method). Create
 // instances with NewSummaryVec.
 // instances with NewSummaryVec.
 type SummaryVec struct {
 type SummaryVec struct {
-	*metricVec
+	*MetricVec
 }
 }
 
 
 // NewSummaryVec creates a new SummaryVec based on the provided SummaryOpts and
 // NewSummaryVec creates a new SummaryVec based on the provided SummaryOpts and
-// partitioned by the given label names.
+// partitioned by the given label names. At least one label name must be
+// provided.
 func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec {
 func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec {
 	desc := NewDesc(
 	desc := NewDesc(
 		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
 		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
@@ -417,60 +404,30 @@ func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec {
 		opts.ConstLabels,
 		opts.ConstLabels,
 	)
 	)
 	return &SummaryVec{
 	return &SummaryVec{
-		metricVec: newMetricVec(desc, func(lvs ...string) Metric {
+		MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
 			return newSummary(desc, opts, lvs...)
 			return newSummary(desc, opts, lvs...)
 		}),
 		}),
 	}
 	}
 }
 }
 
 
-// GetMetricWithLabelValues returns the Summary for the given slice of label
-// values (same order as the VariableLabels in Desc). If that combination of
-// label values is accessed for the first time, a new Summary is created.
-//
-// It is possible to call this method without using the returned Summary to only
-// create the new Summary but leave it at its starting value, a Summary without
-// any observations.
-//
-// Keeping the Summary for later use is possible (and should be considered if
-// performance is critical), but keep in mind that Reset, DeleteLabelValues and
-// Delete can be used to delete the Summary from the SummaryVec. In that case, the
-// Summary will still exist, but it will not be exported anymore, even if a
-// Summary with the same label values is created later. See also the CounterVec
-// example.
-//
-// An error is returned if the number of label values is not the same as the
-// number of VariableLabels in Desc.
-//
-// Note that for more than one label value, this method is prone to mistakes
-// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
-// an alternative to avoid that type of mistake. For higher label numbers, the
-// latter has a much more readable (albeit more verbose) syntax, but it comes
-// with a performance overhead (for creating and processing the Labels map).
-// See also the GaugeVec example.
-func (m *SummaryVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) {
-	metric, err := m.metricVec.getMetricWithLabelValues(lvs...)
+// GetMetricWithLabelValues replaces the method of the same name in
+// MetricVec. The difference is that this method returns a Summary and not a
+// Metric so that no type conversion is required.
+func (m *SummaryVec) GetMetricWithLabelValues(lvs ...string) (Summary, error) {
+	metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...)
 	if metric != nil {
 	if metric != nil {
-		return metric.(Observer), err
+		return metric.(Summary), err
 	}
 	}
 	return nil, err
 	return nil, err
 }
 }
 
 
-// GetMetricWith returns the Summary for the given Labels map (the label names
-// must match those of the VariableLabels in Desc). If that label map is
-// accessed for the first time, a new Summary is created. Implications of
-// creating a Summary without using it and keeping the Summary for later use are
-// the same as for GetMetricWithLabelValues.
-//
-// An error is returned if the number and names of the Labels are inconsistent
-// with those of the VariableLabels in Desc.
-//
-// This method is used for the same purpose as
-// GetMetricWithLabelValues(...string). See there for pros and cons of the two
-// methods.
-func (m *SummaryVec) GetMetricWith(labels Labels) (Observer, error) {
-	metric, err := m.metricVec.getMetricWith(labels)
+// GetMetricWith replaces the method of the same name in MetricVec. The
+// difference is that this method returns a Summary and not a Metric so that no
+// type conversion is required.
+func (m *SummaryVec) GetMetricWith(labels Labels) (Summary, error) {
+	metric, err := m.MetricVec.GetMetricWith(labels)
 	if metric != nil {
 	if metric != nil {
-		return metric.(Observer), err
+		return metric.(Summary), err
 	}
 	}
 	return nil, err
 	return nil, err
 }
 }
@@ -479,15 +436,15 @@ func (m *SummaryVec) GetMetricWith(labels Labels) (Observer, error) {
 // GetMetricWithLabelValues would have returned an error. By not returning an
 // GetMetricWithLabelValues would have returned an error. By not returning an
 // error, WithLabelValues allows shortcuts like
 // error, WithLabelValues allows shortcuts like
 //     myVec.WithLabelValues("404", "GET").Observe(42.21)
 //     myVec.WithLabelValues("404", "GET").Observe(42.21)
-func (m *SummaryVec) WithLabelValues(lvs ...string) Observer {
-	return m.metricVec.withLabelValues(lvs...).(Observer)
+func (m *SummaryVec) WithLabelValues(lvs ...string) Summary {
+	return m.MetricVec.WithLabelValues(lvs...).(Summary)
 }
 }
 
 
 // With works as GetMetricWith, but panics where GetMetricWithLabels would have
 // With works as GetMetricWith, but panics where GetMetricWithLabels would have
 // returned an error. By not returning an error, With allows shortcuts like
 // returned an error. By not returning an error, With allows shortcuts like
 //     myVec.With(Labels{"code": "404", "method": "GET"}).Observe(42.21)
 //     myVec.With(Labels{"code": "404", "method": "GET"}).Observe(42.21)
-func (m *SummaryVec) With(labels Labels) Observer {
-	return m.metricVec.with(labels).(Observer)
+func (m *SummaryVec) With(labels Labels) Summary {
+	return m.MetricVec.With(labels).(Summary)
 }
 }
 
 
 type constSummary struct {
 type constSummary struct {
@@ -548,8 +505,8 @@ func NewConstSummary(
 	quantiles map[float64]float64,
 	quantiles map[float64]float64,
 	labelValues ...string,
 	labelValues ...string,
 ) (Metric, error) {
 ) (Metric, error) {
-	if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil {
-		return nil, err
+	if len(desc.variableLabels) != len(labelValues) {
+		return nil, errInconsistentCardinality
 	}
 	}
 	return &constSummary{
 	return &constSummary{
 		desc:       desc,
 		desc:       desc,

+ 0 - 51
vendor/github.com/prometheus/client_golang/prometheus/timer.go

@@ -1,51 +0,0 @@
-// Copyright 2016 The Prometheus Authors
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package prometheus
-
-import "time"
-
-// Timer is a helper type to time functions. Use NewTimer to create new
-// instances.
-type Timer struct {
-	begin    time.Time
-	observer Observer
-}
-
-// NewTimer creates a new Timer. The provided Observer is used to observe a
-// duration in seconds. Timer is usually used to time a function call in the
-// following way:
-//    func TimeMe() {
-//        timer := NewTimer(myHistogram)
-//        defer timer.ObserveDuration()
-//        // Do actual work.
-//    }
-func NewTimer(o Observer) *Timer {
-	return &Timer{
-		begin:    time.Now(),
-		observer: o,
-	}
-}
-
-// ObserveDuration records the duration passed since the Timer was created with
-// NewTimer. It calls the Observe method of the Observer provided during
-// construction with the duration in seconds as an argument. ObserveDuration is
-// usually called with a defer statement.
-//
-// Note that this method is only guaranteed to never observe negative durations
-// if used with Go1.9+.
-func (t *Timer) ObserveDuration() {
-	if t.observer != nil {
-		t.observer.Observe(time.Since(t.begin).Seconds())
-	}
-}

+ 99 - 3
vendor/github.com/prometheus/client_golang/prometheus/untyped.go

@@ -13,12 +13,108 @@
 
 
 package prometheus
 package prometheus
 
 
+// Untyped is a Metric that represents a single numerical value that can
+// arbitrarily go up and down.
+//
+// An Untyped metric works the same as a Gauge. The only difference is that to
+// no type information is implied.
+//
+// To create Untyped instances, use NewUntyped.
+type Untyped interface {
+	Metric
+	Collector
+
+	// Set sets the Untyped metric to an arbitrary value.
+	Set(float64)
+	// Inc increments the Untyped metric by 1.
+	Inc()
+	// Dec decrements the Untyped metric by 1.
+	Dec()
+	// Add adds the given value to the Untyped metric. (The value can be
+	// negative, resulting in a decrease.)
+	Add(float64)
+	// Sub subtracts the given value from the Untyped metric. (The value can
+	// be negative, resulting in an increase.)
+	Sub(float64)
+}
+
 // UntypedOpts is an alias for Opts. See there for doc comments.
 // UntypedOpts is an alias for Opts. See there for doc comments.
 type UntypedOpts Opts
 type UntypedOpts Opts
 
 
-// UntypedFunc works like GaugeFunc but the collected metric is of type
-// "Untyped". UntypedFunc is useful to mirror an external metric of unknown
-// type.
+// NewUntyped creates a new Untyped metric from the provided UntypedOpts.
+func NewUntyped(opts UntypedOpts) Untyped {
+	return newValue(NewDesc(
+		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
+		opts.Help,
+		nil,
+		opts.ConstLabels,
+	), UntypedValue, 0)
+}
+
+// UntypedVec is a Collector that bundles a set of Untyped metrics that all
+// share the same Desc, but have different values for their variable
+// labels. This is used if you want to count the same thing partitioned by
+// various dimensions. Create instances with NewUntypedVec.
+type UntypedVec struct {
+	*MetricVec
+}
+
+// NewUntypedVec creates a new UntypedVec based on the provided UntypedOpts and
+// partitioned by the given label names. At least one label name must be
+// provided.
+func NewUntypedVec(opts UntypedOpts, labelNames []string) *UntypedVec {
+	desc := NewDesc(
+		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
+		opts.Help,
+		labelNames,
+		opts.ConstLabels,
+	)
+	return &UntypedVec{
+		MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
+			return newValue(desc, UntypedValue, 0, lvs...)
+		}),
+	}
+}
+
+// GetMetricWithLabelValues replaces the method of the same name in
+// MetricVec. The difference is that this method returns an Untyped and not a
+// Metric so that no type conversion is required.
+func (m *UntypedVec) GetMetricWithLabelValues(lvs ...string) (Untyped, error) {
+	metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...)
+	if metric != nil {
+		return metric.(Untyped), err
+	}
+	return nil, err
+}
+
+// GetMetricWith replaces the method of the same name in MetricVec. The
+// difference is that this method returns an Untyped and not a Metric so that no
+// type conversion is required.
+func (m *UntypedVec) GetMetricWith(labels Labels) (Untyped, error) {
+	metric, err := m.MetricVec.GetMetricWith(labels)
+	if metric != nil {
+		return metric.(Untyped), err
+	}
+	return nil, err
+}
+
+// WithLabelValues works as GetMetricWithLabelValues, but panics where
+// GetMetricWithLabelValues would have returned an error. By not returning an
+// error, WithLabelValues allows shortcuts like
+//     myVec.WithLabelValues("404", "GET").Add(42)
+func (m *UntypedVec) WithLabelValues(lvs ...string) Untyped {
+	return m.MetricVec.WithLabelValues(lvs...).(Untyped)
+}
+
+// With works as GetMetricWith, but panics where GetMetricWithLabels would have
+// returned an error. By not returning an error, With allows shortcuts like
+//     myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
+func (m *UntypedVec) With(labels Labels) Untyped {
+	return m.MetricVec.With(labels).(Untyped)
+}
+
+// UntypedFunc is an Untyped whose value is determined at collect time by
+// calling a provided function.
 //
 //
 // To create UntypedFunc instances, use NewUntypedFunc.
 // To create UntypedFunc instances, use NewUntypedFunc.
 type UntypedFunc interface {
 type UntypedFunc interface {

+ 6 - 8
vendor/github.com/prometheus/client_golang/prometheus/value.go

@@ -14,11 +14,11 @@
 package prometheus
 package prometheus
 
 
 import (
 import (
+	"errors"
 	"fmt"
 	"fmt"
 	"math"
 	"math"
 	"sort"
 	"sort"
 	"sync/atomic"
 	"sync/atomic"
-	"time"
 
 
 	dto "github.com/prometheus/client_model/go"
 	dto "github.com/prometheus/client_model/go"
 
 
@@ -36,12 +36,14 @@ const (
 	UntypedValue
 	UntypedValue
 )
 )
 
 
+var errInconsistentCardinality = errors.New("inconsistent label cardinality")
+
 // value is a generic metric for simple values. It implements Metric, Collector,
 // value is a generic metric for simple values. It implements Metric, Collector,
 // Counter, Gauge, and Untyped. Its effective type is determined by
 // Counter, Gauge, and Untyped. Its effective type is determined by
 // ValueType. This is a low-level building block used by the library to back the
 // ValueType. This is a low-level building block used by the library to back the
 // implementations of Counter, Gauge, and Untyped.
 // implementations of Counter, Gauge, and Untyped.
 type value struct {
 type value struct {
-	// valBits contains the bits of the represented float64 value. It has
+	// valBits containst the bits of the represented float64 value. It has
 	// to go first in the struct to guarantee alignment for atomic
 	// to go first in the struct to guarantee alignment for atomic
 	// operations.  http://golang.org/pkg/sync/atomic/#pkg-note-BUG
 	// operations.  http://golang.org/pkg/sync/atomic/#pkg-note-BUG
 	valBits uint64
 	valBits uint64
@@ -78,10 +80,6 @@ func (v *value) Set(val float64) {
 	atomic.StoreUint64(&v.valBits, math.Float64bits(val))
 	atomic.StoreUint64(&v.valBits, math.Float64bits(val))
 }
 }
 
 
-func (v *value) SetToCurrentTime() {
-	v.Set(float64(time.Now().UnixNano()) / 1e9)
-}
-
 func (v *value) Inc() {
 func (v *value) Inc() {
 	v.Add(1)
 	v.Add(1)
 }
 }
@@ -155,8 +153,8 @@ func (v *valueFunc) Write(out *dto.Metric) error {
 // the Collect method. NewConstMetric returns an error if the length of
 // the Collect method. NewConstMetric returns an error if the length of
 // labelValues is not consistent with the variable labels in Desc.
 // labelValues is not consistent with the variable labels in Desc.
 func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) (Metric, error) {
 func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) (Metric, error) {
-	if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil {
-		return nil, err
+	if len(desc.variableLabels) != len(labelValues) {
+		return nil, errInconsistentCardinality
 	}
 	}
 	return &constMetric{
 	return &constMetric{
 		desc:       desc,
 		desc:       desc,

+ 92 - 51
vendor/github.com/prometheus/client_golang/prometheus/vec.go

@@ -20,12 +20,12 @@ import (
 	"github.com/prometheus/common/model"
 	"github.com/prometheus/common/model"
 )
 )
 
 
-// metricVec is a Collector to bundle metrics of the same name that differ in
-// their label values. metricVec is not used directly (and therefore
-// unexported). It is used as a building block for implementations of vectors of
-// a given metric type, like GaugeVec, CounterVec, SummaryVec, HistogramVec, and
-// UntypedVec.
-type metricVec struct {
+// MetricVec is a Collector to bundle metrics of the same name that
+// differ in their label values. MetricVec is usually not used directly but as a
+// building block for implementations of vectors of a given metric
+// type. GaugeVec, CounterVec, SummaryVec, and UntypedVec are examples already
+// provided in this package.
+type MetricVec struct {
 	mtx      sync.RWMutex // Protects the children.
 	mtx      sync.RWMutex // Protects the children.
 	children map[uint64][]metricWithLabelValues
 	children map[uint64][]metricWithLabelValues
 	desc     *Desc
 	desc     *Desc
@@ -35,9 +35,10 @@ type metricVec struct {
 	hashAddByte func(h uint64, b byte) uint64
 	hashAddByte func(h uint64, b byte) uint64
 }
 }
 
 
-// newMetricVec returns an initialized metricVec.
-func newMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *metricVec {
-	return &metricVec{
+// newMetricVec returns an initialized MetricVec. The concrete value is
+// returned for embedding into another struct.
+func newMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *MetricVec {
+	return &MetricVec{
 		children:    map[uint64][]metricWithLabelValues{},
 		children:    map[uint64][]metricWithLabelValues{},
 		desc:        desc,
 		desc:        desc,
 		newMetric:   newMetric,
 		newMetric:   newMetric,
@@ -55,12 +56,12 @@ type metricWithLabelValues struct {
 
 
 // Describe implements Collector. The length of the returned slice
 // Describe implements Collector. The length of the returned slice
 // is always one.
 // is always one.
-func (m *metricVec) Describe(ch chan<- *Desc) {
+func (m *MetricVec) Describe(ch chan<- *Desc) {
 	ch <- m.desc
 	ch <- m.desc
 }
 }
 
 
 // Collect implements Collector.
 // Collect implements Collector.
-func (m *metricVec) Collect(ch chan<- Metric) {
+func (m *MetricVec) Collect(ch chan<- Metric) {
 	m.mtx.RLock()
 	m.mtx.RLock()
 	defer m.mtx.RUnlock()
 	defer m.mtx.RUnlock()
 
 
@@ -71,7 +72,31 @@ func (m *metricVec) Collect(ch chan<- Metric) {
 	}
 	}
 }
 }
 
 
-func (m *metricVec) getMetricWithLabelValues(lvs ...string) (Metric, error) {
+// GetMetricWithLabelValues returns the Metric for the given slice of label
+// values (same order as the VariableLabels in Desc). If that combination of
+// label values is accessed for the first time, a new Metric is created.
+//
+// It is possible to call this method without using the returned Metric to only
+// create the new Metric but leave it at its start value (e.g. a Summary or
+// Histogram without any observations). See also the SummaryVec example.
+//
+// Keeping the Metric for later use is possible (and should be considered if
+// performance is critical), but keep in mind that Reset, DeleteLabelValues and
+// Delete can be used to delete the Metric from the MetricVec. In that case, the
+// Metric will still exist, but it will not be exported anymore, even if a
+// Metric with the same label values is created later. See also the CounterVec
+// example.
+//
+// An error is returned if the number of label values is not the same as the
+// number of VariableLabels in Desc.
+//
+// Note that for more than one label value, this method is prone to mistakes
+// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as
+// an alternative to avoid that type of mistake. For higher label numbers, the
+// latter has a much more readable (albeit more verbose) syntax, but it comes
+// with a performance overhead (for creating and processing the Labels map).
+// See also the GaugeVec example.
+func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) {
 	h, err := m.hashLabelValues(lvs)
 	h, err := m.hashLabelValues(lvs)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -80,7 +105,19 @@ func (m *metricVec) getMetricWithLabelValues(lvs ...string) (Metric, error) {
 	return m.getOrCreateMetricWithLabelValues(h, lvs), nil
 	return m.getOrCreateMetricWithLabelValues(h, lvs), nil
 }
 }
 
 
-func (m *metricVec) getMetricWith(labels Labels) (Metric, error) {
+// GetMetricWith returns the Metric for the given Labels map (the label names
+// must match those of the VariableLabels in Desc). If that label map is
+// accessed for the first time, a new Metric is created. Implications of
+// creating a Metric without using it and keeping the Metric for later use are
+// the same as for GetMetricWithLabelValues.
+//
+// An error is returned if the number and names of the Labels are inconsistent
+// with those of the VariableLabels in Desc.
+//
+// This method is used for the same purpose as
+// GetMetricWithLabelValues(...string). See there for pros and cons of the two
+// methods.
+func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) {
 	h, err := m.hashLabels(labels)
 	h, err := m.hashLabels(labels)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -89,16 +126,22 @@ func (m *metricVec) getMetricWith(labels Labels) (Metric, error) {
 	return m.getOrCreateMetricWithLabels(h, labels), nil
 	return m.getOrCreateMetricWithLabels(h, labels), nil
 }
 }
 
 
-func (m *metricVec) withLabelValues(lvs ...string) Metric {
-	metric, err := m.getMetricWithLabelValues(lvs...)
+// WithLabelValues works as GetMetricWithLabelValues, but panics if an error
+// occurs. The method allows neat syntax like:
+//     httpReqs.WithLabelValues("404", "POST").Inc()
+func (m *MetricVec) WithLabelValues(lvs ...string) Metric {
+	metric, err := m.GetMetricWithLabelValues(lvs...)
 	if err != nil {
 	if err != nil {
 		panic(err)
 		panic(err)
 	}
 	}
 	return metric
 	return metric
 }
 }
 
 
-func (m *metricVec) with(labels Labels) Metric {
-	metric, err := m.getMetricWith(labels)
+// With works as GetMetricWith, but panics if an error occurs. The method allows
+// neat syntax like:
+//     httpReqs.With(Labels{"status":"404", "method":"POST"}).Inc()
+func (m *MetricVec) With(labels Labels) Metric {
+	metric, err := m.GetMetricWith(labels)
 	if err != nil {
 	if err != nil {
 		panic(err)
 		panic(err)
 	}
 	}
@@ -110,8 +153,8 @@ func (m *metricVec) with(labels Labels) Metric {
 // returns true if a metric was deleted.
 // returns true if a metric was deleted.
 //
 //
 // It is not an error if the number of label values is not the same as the
 // It is not an error if the number of label values is not the same as the
-// number of VariableLabels in Desc. However, such inconsistent label count can
-// never match an actual metric, so the method will always return false in that
+// number of VariableLabels in Desc.  However, such inconsistent label count can
+// never match an actual Metric, so the method will always return false in that
 // case.
 // case.
 //
 //
 // Note that for more than one label value, this method is prone to mistakes
 // Note that for more than one label value, this method is prone to mistakes
@@ -120,7 +163,7 @@ func (m *metricVec) with(labels Labels) Metric {
 // latter has a much more readable (albeit more verbose) syntax, but it comes
 // latter has a much more readable (albeit more verbose) syntax, but it comes
 // with a performance overhead (for creating and processing the Labels map).
 // with a performance overhead (for creating and processing the Labels map).
 // See also the CounterVec example.
 // See also the CounterVec example.
-func (m *metricVec) DeleteLabelValues(lvs ...string) bool {
+func (m *MetricVec) DeleteLabelValues(lvs ...string) bool {
 	m.mtx.Lock()
 	m.mtx.Lock()
 	defer m.mtx.Unlock()
 	defer m.mtx.Unlock()
 
 
@@ -135,13 +178,13 @@ func (m *metricVec) DeleteLabelValues(lvs ...string) bool {
 // passed in as labels. It returns true if a metric was deleted.
 // passed in as labels. It returns true if a metric was deleted.
 //
 //
 // It is not an error if the number and names of the Labels are inconsistent
 // It is not an error if the number and names of the Labels are inconsistent
-// with those of the VariableLabels in Desc. However, such inconsistent Labels
-// can never match an actual metric, so the method will always return false in
-// that case.
+// with those of the VariableLabels in the Desc of the MetricVec. However, such
+// inconsistent Labels can never match an actual Metric, so the method will
+// always return false in that case.
 //
 //
 // This method is used for the same purpose as DeleteLabelValues(...string). See
 // This method is used for the same purpose as DeleteLabelValues(...string). See
 // there for pros and cons of the two methods.
 // there for pros and cons of the two methods.
-func (m *metricVec) Delete(labels Labels) bool {
+func (m *MetricVec) Delete(labels Labels) bool {
 	m.mtx.Lock()
 	m.mtx.Lock()
 	defer m.mtx.Unlock()
 	defer m.mtx.Unlock()
 
 
@@ -156,7 +199,7 @@ func (m *metricVec) Delete(labels Labels) bool {
 // deleteByHashWithLabelValues removes the metric from the hash bucket h. If
 // deleteByHashWithLabelValues removes the metric from the hash bucket h. If
 // there are multiple matches in the bucket, use lvs to select a metric and
 // there are multiple matches in the bucket, use lvs to select a metric and
 // remove only that metric.
 // remove only that metric.
-func (m *metricVec) deleteByHashWithLabelValues(h uint64, lvs []string) bool {
+func (m *MetricVec) deleteByHashWithLabelValues(h uint64, lvs []string) bool {
 	metrics, ok := m.children[h]
 	metrics, ok := m.children[h]
 	if !ok {
 	if !ok {
 		return false
 		return false
@@ -178,7 +221,7 @@ func (m *metricVec) deleteByHashWithLabelValues(h uint64, lvs []string) bool {
 // deleteByHashWithLabels removes the metric from the hash bucket h. If there
 // deleteByHashWithLabels removes the metric from the hash bucket h. If there
 // are multiple matches in the bucket, use lvs to select a metric and remove
 // are multiple matches in the bucket, use lvs to select a metric and remove
 // only that metric.
 // only that metric.
-func (m *metricVec) deleteByHashWithLabels(h uint64, labels Labels) bool {
+func (m *MetricVec) deleteByHashWithLabels(h uint64, labels Labels) bool {
 	metrics, ok := m.children[h]
 	metrics, ok := m.children[h]
 	if !ok {
 	if !ok {
 		return false
 		return false
@@ -197,7 +240,7 @@ func (m *metricVec) deleteByHashWithLabels(h uint64, labels Labels) bool {
 }
 }
 
 
 // Reset deletes all metrics in this vector.
 // Reset deletes all metrics in this vector.
-func (m *metricVec) Reset() {
+func (m *MetricVec) Reset() {
 	m.mtx.Lock()
 	m.mtx.Lock()
 	defer m.mtx.Unlock()
 	defer m.mtx.Unlock()
 
 
@@ -206,11 +249,10 @@ func (m *metricVec) Reset() {
 	}
 	}
 }
 }
 
 
-func (m *metricVec) hashLabelValues(vals []string) (uint64, error) {
-	if err := validateLabelValues(vals, len(m.desc.variableLabels)); err != nil {
-		return 0, err
+func (m *MetricVec) hashLabelValues(vals []string) (uint64, error) {
+	if len(vals) != len(m.desc.variableLabels) {
+		return 0, errInconsistentCardinality
 	}
 	}
-
 	h := hashNew()
 	h := hashNew()
 	for _, val := range vals {
 	for _, val := range vals {
 		h = m.hashAdd(h, val)
 		h = m.hashAdd(h, val)
@@ -219,11 +261,10 @@ func (m *metricVec) hashLabelValues(vals []string) (uint64, error) {
 	return h, nil
 	return h, nil
 }
 }
 
 
-func (m *metricVec) hashLabels(labels Labels) (uint64, error) {
-	if err := validateValuesInLabels(labels, len(m.desc.variableLabels)); err != nil {
-		return 0, err
+func (m *MetricVec) hashLabels(labels Labels) (uint64, error) {
+	if len(labels) != len(m.desc.variableLabels) {
+		return 0, errInconsistentCardinality
 	}
 	}
-
 	h := hashNew()
 	h := hashNew()
 	for _, label := range m.desc.variableLabels {
 	for _, label := range m.desc.variableLabels {
 		val, ok := labels[label]
 		val, ok := labels[label]
@@ -240,9 +281,9 @@ func (m *metricVec) hashLabels(labels Labels) (uint64, error) {
 // or creates it and returns the new one.
 // or creates it and returns the new one.
 //
 //
 // This function holds the mutex.
 // This function holds the mutex.
-func (m *metricVec) getOrCreateMetricWithLabelValues(hash uint64, lvs []string) Metric {
+func (m *MetricVec) getOrCreateMetricWithLabelValues(hash uint64, lvs []string) Metric {
 	m.mtx.RLock()
 	m.mtx.RLock()
-	metric, ok := m.getMetricWithHashAndLabelValues(hash, lvs)
+	metric, ok := m.getMetricWithLabelValues(hash, lvs)
 	m.mtx.RUnlock()
 	m.mtx.RUnlock()
 	if ok {
 	if ok {
 		return metric
 		return metric
@@ -250,7 +291,7 @@ func (m *metricVec) getOrCreateMetricWithLabelValues(hash uint64, lvs []string)
 
 
 	m.mtx.Lock()
 	m.mtx.Lock()
 	defer m.mtx.Unlock()
 	defer m.mtx.Unlock()
-	metric, ok = m.getMetricWithHashAndLabelValues(hash, lvs)
+	metric, ok = m.getMetricWithLabelValues(hash, lvs)
 	if !ok {
 	if !ok {
 		// Copy to avoid allocation in case wo don't go down this code path.
 		// Copy to avoid allocation in case wo don't go down this code path.
 		copiedLVs := make([]string, len(lvs))
 		copiedLVs := make([]string, len(lvs))
@@ -265,9 +306,9 @@ func (m *metricVec) getOrCreateMetricWithLabelValues(hash uint64, lvs []string)
 // or creates it and returns the new one.
 // or creates it and returns the new one.
 //
 //
 // This function holds the mutex.
 // This function holds the mutex.
-func (m *metricVec) getOrCreateMetricWithLabels(hash uint64, labels Labels) Metric {
+func (m *MetricVec) getOrCreateMetricWithLabels(hash uint64, labels Labels) Metric {
 	m.mtx.RLock()
 	m.mtx.RLock()
-	metric, ok := m.getMetricWithHashAndLabels(hash, labels)
+	metric, ok := m.getMetricWithLabels(hash, labels)
 	m.mtx.RUnlock()
 	m.mtx.RUnlock()
 	if ok {
 	if ok {
 		return metric
 		return metric
@@ -275,7 +316,7 @@ func (m *metricVec) getOrCreateMetricWithLabels(hash uint64, labels Labels) Metr
 
 
 	m.mtx.Lock()
 	m.mtx.Lock()
 	defer m.mtx.Unlock()
 	defer m.mtx.Unlock()
-	metric, ok = m.getMetricWithHashAndLabels(hash, labels)
+	metric, ok = m.getMetricWithLabels(hash, labels)
 	if !ok {
 	if !ok {
 		lvs := m.extractLabelValues(labels)
 		lvs := m.extractLabelValues(labels)
 		metric = m.newMetric(lvs...)
 		metric = m.newMetric(lvs...)
@@ -284,9 +325,9 @@ func (m *metricVec) getOrCreateMetricWithLabels(hash uint64, labels Labels) Metr
 	return metric
 	return metric
 }
 }
 
 
-// getMetricWithHashAndLabelValues gets a metric while handling possible
-// collisions in the hash space. Must be called while holding the read mutex.
-func (m *metricVec) getMetricWithHashAndLabelValues(h uint64, lvs []string) (Metric, bool) {
+// getMetricWithLabelValues gets a metric while handling possible collisions in
+// the hash space. Must be called while holding read mutex.
+func (m *MetricVec) getMetricWithLabelValues(h uint64, lvs []string) (Metric, bool) {
 	metrics, ok := m.children[h]
 	metrics, ok := m.children[h]
 	if ok {
 	if ok {
 		if i := m.findMetricWithLabelValues(metrics, lvs); i < len(metrics) {
 		if i := m.findMetricWithLabelValues(metrics, lvs); i < len(metrics) {
@@ -296,9 +337,9 @@ func (m *metricVec) getMetricWithHashAndLabelValues(h uint64, lvs []string) (Met
 	return nil, false
 	return nil, false
 }
 }
 
 
-// getMetricWithHashAndLabels gets a metric while handling possible collisions in
+// getMetricWithLabels gets a metric while handling possible collisions in
 // the hash space. Must be called while holding read mutex.
 // the hash space. Must be called while holding read mutex.
-func (m *metricVec) getMetricWithHashAndLabels(h uint64, labels Labels) (Metric, bool) {
+func (m *MetricVec) getMetricWithLabels(h uint64, labels Labels) (Metric, bool) {
 	metrics, ok := m.children[h]
 	metrics, ok := m.children[h]
 	if ok {
 	if ok {
 		if i := m.findMetricWithLabels(metrics, labels); i < len(metrics) {
 		if i := m.findMetricWithLabels(metrics, labels); i < len(metrics) {
@@ -310,7 +351,7 @@ func (m *metricVec) getMetricWithHashAndLabels(h uint64, labels Labels) (Metric,
 
 
 // findMetricWithLabelValues returns the index of the matching metric or
 // findMetricWithLabelValues returns the index of the matching metric or
 // len(metrics) if not found.
 // len(metrics) if not found.
-func (m *metricVec) findMetricWithLabelValues(metrics []metricWithLabelValues, lvs []string) int {
+func (m *MetricVec) findMetricWithLabelValues(metrics []metricWithLabelValues, lvs []string) int {
 	for i, metric := range metrics {
 	for i, metric := range metrics {
 		if m.matchLabelValues(metric.values, lvs) {
 		if m.matchLabelValues(metric.values, lvs) {
 			return i
 			return i
@@ -321,7 +362,7 @@ func (m *metricVec) findMetricWithLabelValues(metrics []metricWithLabelValues, l
 
 
 // findMetricWithLabels returns the index of the matching metric or len(metrics)
 // findMetricWithLabels returns the index of the matching metric or len(metrics)
 // if not found.
 // if not found.
-func (m *metricVec) findMetricWithLabels(metrics []metricWithLabelValues, labels Labels) int {
+func (m *MetricVec) findMetricWithLabels(metrics []metricWithLabelValues, labels Labels) int {
 	for i, metric := range metrics {
 	for i, metric := range metrics {
 		if m.matchLabels(metric.values, labels) {
 		if m.matchLabels(metric.values, labels) {
 			return i
 			return i
@@ -330,7 +371,7 @@ func (m *metricVec) findMetricWithLabels(metrics []metricWithLabelValues, labels
 	return len(metrics)
 	return len(metrics)
 }
 }
 
 
-func (m *metricVec) matchLabelValues(values []string, lvs []string) bool {
+func (m *MetricVec) matchLabelValues(values []string, lvs []string) bool {
 	if len(values) != len(lvs) {
 	if len(values) != len(lvs) {
 		return false
 		return false
 	}
 	}
@@ -342,7 +383,7 @@ func (m *metricVec) matchLabelValues(values []string, lvs []string) bool {
 	return true
 	return true
 }
 }
 
 
-func (m *metricVec) matchLabels(values []string, labels Labels) bool {
+func (m *MetricVec) matchLabels(values []string, labels Labels) bool {
 	if len(labels) != len(values) {
 	if len(labels) != len(values) {
 		return false
 		return false
 	}
 	}
@@ -354,7 +395,7 @@ func (m *metricVec) matchLabels(values []string, labels Labels) bool {
 	return true
 	return true
 }
 }
 
 
-func (m *metricVec) extractLabelValues(labels Labels) []string {
+func (m *MetricVec) extractLabelValues(labels Labels) []string {
 	labelValues := make([]string, len(labels))
 	labelValues := make([]string, len(labels))
 	for i, k := range m.desc.variableLabels {
 	for i, k := range m.desc.variableLabels {
 		labelValues[i] = labels[k]
 		labelValues[i] = labels[k]

+ 2 - 2
vendor/github.com/prometheus/common/expfmt/decode.go

@@ -164,9 +164,9 @@ func (sd *SampleDecoder) Decode(s *model.Vector) error {
 }
 }
 
 
 // ExtractSamples builds a slice of samples from the provided metric
 // ExtractSamples builds a slice of samples from the provided metric
-// families. If an error occurs during sample extraction, it continues to
+// families. If an error occurrs during sample extraction, it continues to
 // extract from the remaining metric families. The returned error is the last
 // extract from the remaining metric families. The returned error is the last
-// error that has occured.
+// error that has occurred.
 func ExtractSamples(o *DecodeOptions, fams ...*dto.MetricFamily) (model.Vector, error) {
 func ExtractSamples(o *DecodeOptions, fams ...*dto.MetricFamily) (model.Vector, error) {
 	var (
 	var (
 		all     model.Vector
 		all     model.Vector

+ 1 - 1
vendor/github.com/prometheus/common/expfmt/expfmt.go

@@ -26,7 +26,7 @@ const (
 
 
 	// The Content-Type values for the different wire protocols.
 	// The Content-Type values for the different wire protocols.
 	FmtUnknown      Format = `<unknown>`
 	FmtUnknown      Format = `<unknown>`
-	FmtText         Format = `text/plain; version=` + TextVersion
+	FmtText         Format = `text/plain; version=` + TextVersion + `; charset=utf-8`
 	FmtProtoDelim   Format = ProtoFmt + ` encoding=delimited`
 	FmtProtoDelim   Format = ProtoFmt + ` encoding=delimited`
 	FmtProtoText    Format = ProtoFmt + ` encoding=text`
 	FmtProtoText    Format = ProtoFmt + ` encoding=text`
 	FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text`
 	FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text`

+ 2 - 2
vendor/github.com/prometheus/common/expfmt/text_parse.go

@@ -556,8 +556,8 @@ func (p *TextParser) readTokenUntilWhitespace() {
 // byte considered is the byte already read (now in p.currentByte).  The first
 // byte considered is the byte already read (now in p.currentByte).  The first
 // newline byte encountered is still copied into p.currentByte, but not into
 // newline byte encountered is still copied into p.currentByte, but not into
 // p.currentToken. If recognizeEscapeSequence is true, two escape sequences are
 // p.currentToken. If recognizeEscapeSequence is true, two escape sequences are
-// recognized: '\\' tranlates into '\', and '\n' into a line-feed character. All
-// other escape sequences are invalid and cause an error.
+// recognized: '\\' translates into '\', and '\n' into a line-feed character.
+// All other escape sequences are invalid and cause an error.
 func (p *TextParser) readTokenUntilNewline(recognizeEscapeSequence bool) {
 func (p *TextParser) readTokenUntilNewline(recognizeEscapeSequence bool) {
 	p.currentToken.Reset()
 	p.currentToken.Reset()
 	escaped := false
 	escaped := false

+ 2 - 2
vendor/github.com/prometheus/common/model/silence.go

@@ -59,8 +59,8 @@ func (m *Matcher) Validate() error {
 	return nil
 	return nil
 }
 }
 
 
-// Silence defines the representation of a silence definiton
-// in the Prometheus eco-system.
+// Silence defines the representation of a silence definition in the Prometheus
+// eco-system.
 type Silence struct {
 type Silence struct {
 	ID uint64 `json:"id,omitempty"`
 	ID uint64 `json:"id,omitempty"`
 
 

+ 3 - 0
vendor/github.com/prometheus/common/model/time.go

@@ -214,6 +214,9 @@ func (d Duration) String() string {
 		ms   = int64(time.Duration(d) / time.Millisecond)
 		ms   = int64(time.Duration(d) / time.Millisecond)
 		unit = "ms"
 		unit = "ms"
 	)
 	)
+	if ms == 0 {
+		return "0s"
+	}
 	factors := map[string]int64{
 	factors := map[string]int64{
 		"y":  1000 * 60 * 60 * 24 * 365,
 		"y":  1000 * 60 * 60 * 24 * 365,
 		"w":  1000 * 60 * 60 * 24 * 7,
 		"w":  1000 * 60 * 60 * 24 * 7,

+ 2 - 2
vendor/github.com/prometheus/common/model/value.go

@@ -100,7 +100,7 @@ func (s *SamplePair) UnmarshalJSON(b []byte) error {
 }
 }
 
 
 // Equal returns true if this SamplePair and o have equal Values and equal
 // Equal returns true if this SamplePair and o have equal Values and equal
-// Timestamps. The sematics of Value equality is defined by SampleValue.Equal.
+// Timestamps. The semantics of Value equality is defined by SampleValue.Equal.
 func (s *SamplePair) Equal(o *SamplePair) bool {
 func (s *SamplePair) Equal(o *SamplePair) bool {
 	return s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp))
 	return s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp))
 }
 }
@@ -117,7 +117,7 @@ type Sample struct {
 }
 }
 
 
 // Equal compares first the metrics, then the timestamp, then the value. The
 // Equal compares first the metrics, then the timestamp, then the value. The
-// sematics of value equality is defined by SampleValue.Equal.
+// semantics of value equality is defined by SampleValue.Equal.
 func (s *Sample) Equal(o *Sample) bool {
 func (s *Sample) Equal(o *Sample) bool {
 	if s == o {
 	if s == o {
 		return true
 		return true

+ 1 - 1
vendor/github.com/prometheus/procfs/buddyinfo.go

@@ -62,7 +62,7 @@ func parseBuddyInfo(r io.Reader) ([]BuddyInfo, error) {
 	for scanner.Scan() {
 	for scanner.Scan() {
 		var err error
 		var err error
 		line := scanner.Text()
 		line := scanner.Text()
-		parts := strings.Fields(string(line))
+		parts := strings.Fields(line)
 
 
 		if len(parts) < 4 {
 		if len(parts) < 4 {
 			return nil, fmt.Errorf("invalid number of fields when parsing buddyinfo")
 			return nil, fmt.Errorf("invalid number of fields when parsing buddyinfo")

+ 36 - 0
vendor/github.com/prometheus/procfs/fs.go

@@ -1,3 +1,16 @@
+// Copyright 2018 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package procfs
 package procfs
 
 
 import (
 import (
@@ -5,6 +18,7 @@ import (
 	"os"
 	"os"
 	"path"
 	"path"
 
 
+	"github.com/prometheus/procfs/nfs"
 	"github.com/prometheus/procfs/xfs"
 	"github.com/prometheus/procfs/xfs"
 )
 )
 
 
@@ -44,3 +58,25 @@ func (fs FS) XFSStats() (*xfs.Stats, error) {
 
 
 	return xfs.ParseStats(f)
 	return xfs.ParseStats(f)
 }
 }
+
+// NFSClientRPCStats retrieves NFS client RPC statistics.
+func (fs FS) NFSClientRPCStats() (*nfs.ClientRPCStats, error) {
+	f, err := os.Open(fs.Path("net/rpc/nfs"))
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+
+	return nfs.ParseClientRPCStats(f)
+}
+
+// NFSdServerRPCStats retrieves NFS daemon RPC statistics.
+func (fs FS) NFSdServerRPCStats() (*nfs.ServerRPCStats, error) {
+	f, err := os.Open(fs.Path("net/rpc/nfsd"))
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+
+	return nfs.ParseServerRPCStats(f)
+}

+ 46 - 0
vendor/github.com/prometheus/procfs/internal/util/parse.go

@@ -0,0 +1,46 @@
+// Copyright 2018 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package util
+
+import "strconv"
+
+// ParseUint32s parses a slice of strings into a slice of uint32s.
+func ParseUint32s(ss []string) ([]uint32, error) {
+	us := make([]uint32, 0, len(ss))
+	for _, s := range ss {
+		u, err := strconv.ParseUint(s, 10, 32)
+		if err != nil {
+			return nil, err
+		}
+
+		us = append(us, uint32(u))
+	}
+
+	return us, nil
+}
+
+// ParseUint64s parses a slice of strings into a slice of uint64s.
+func ParseUint64s(ss []string) ([]uint64, error) {
+	us := make([]uint64, 0, len(ss))
+	for _, s := range ss {
+		u, err := strconv.ParseUint(s, 10, 64)
+		if err != nil {
+			return nil, err
+		}
+
+		us = append(us, u)
+	}
+
+	return us, nil
+}

+ 18 - 5
vendor/github.com/prometheus/procfs/ipvs.go

@@ -1,3 +1,16 @@
+// Copyright 2018 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package procfs
 package procfs
 
 
 import (
 import (
@@ -31,16 +44,16 @@ type IPVSStats struct {
 type IPVSBackendStatus struct {
 type IPVSBackendStatus struct {
 	// The local (virtual) IP address.
 	// The local (virtual) IP address.
 	LocalAddress net.IP
 	LocalAddress net.IP
+	// The remote (real) IP address.
+	RemoteAddress net.IP
 	// The local (virtual) port.
 	// The local (virtual) port.
 	LocalPort uint16
 	LocalPort uint16
+	// The remote (real) port.
+	RemotePort uint16
 	// The local firewall mark
 	// The local firewall mark
 	LocalMark string
 	LocalMark string
 	// The transport protocol (TCP, UDP).
 	// The transport protocol (TCP, UDP).
 	Proto string
 	Proto string
-	// The remote (real) IP address.
-	RemoteAddress net.IP
-	// The remote (real) port.
-	RemotePort uint16
 	// The current number of active connections for this virtual/real address pair.
 	// The current number of active connections for this virtual/real address pair.
 	ActiveConn uint64
 	ActiveConn uint64
 	// The current number of inactive connections for this virtual/real address pair.
 	// The current number of inactive connections for this virtual/real address pair.
@@ -151,7 +164,7 @@ func parseIPVSBackendStatus(file io.Reader) ([]IPVSBackendStatus, error) {
 	)
 	)
 
 
 	for scanner.Scan() {
 	for scanner.Scan() {
-		fields := strings.Fields(string(scanner.Text()))
+		fields := strings.Fields(scanner.Text())
 		if len(fields) == 0 {
 		if len(fields) == 0 {
 			continue
 			continue
 		}
 		}

+ 13 - 0
vendor/github.com/prometheus/procfs/mdstat.go

@@ -1,3 +1,16 @@
+// Copyright 2018 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package procfs
 package procfs
 
 
 import (
 import (

+ 13 - 0
vendor/github.com/prometheus/procfs/mountstats.go

@@ -1,3 +1,16 @@
+// Copyright 2018 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package procfs
 package procfs
 
 
 // While implementing parsing of /proc/[pid]/mountstats, this blog was used
 // While implementing parsing of /proc/[pid]/mountstats, this blog was used

+ 216 - 0
vendor/github.com/prometheus/procfs/net_dev.go

@@ -0,0 +1,216 @@
+// Copyright 2018 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package procfs
+
+import (
+	"bufio"
+	"errors"
+	"os"
+	"sort"
+	"strconv"
+	"strings"
+)
+
+// NetDevLine is single line parsed from /proc/net/dev or /proc/[pid]/net/dev.
+type NetDevLine struct {
+	Name         string `json:"name"`          // The name of the interface.
+	RxBytes      uint64 `json:"rx_bytes"`      // Cumulative count of bytes received.
+	RxPackets    uint64 `json:"rx_packets"`    // Cumulative count of packets received.
+	RxErrors     uint64 `json:"rx_errors"`     // Cumulative count of receive errors encountered.
+	RxDropped    uint64 `json:"rx_dropped"`    // Cumulative count of packets dropped while receiving.
+	RxFIFO       uint64 `json:"rx_fifo"`       // Cumulative count of FIFO buffer errors.
+	RxFrame      uint64 `json:"rx_frame"`      // Cumulative count of packet framing errors.
+	RxCompressed uint64 `json:"rx_compressed"` // Cumulative count of compressed packets received by the device driver.
+	RxMulticast  uint64 `json:"rx_multicast"`  // Cumulative count of multicast frames received by the device driver.
+	TxBytes      uint64 `json:"tx_bytes"`      // Cumulative count of bytes transmitted.
+	TxPackets    uint64 `json:"tx_packets"`    // Cumulative count of packets transmitted.
+	TxErrors     uint64 `json:"tx_errors"`     // Cumulative count of transmit errors encountered.
+	TxDropped    uint64 `json:"tx_dropped"`    // Cumulative count of packets dropped while transmitting.
+	TxFIFO       uint64 `json:"tx_fifo"`       // Cumulative count of FIFO buffer errors.
+	TxCollisions uint64 `json:"tx_collisions"` // Cumulative count of collisions detected on the interface.
+	TxCarrier    uint64 `json:"tx_carrier"`    // Cumulative count of carrier losses detected by the device driver.
+	TxCompressed uint64 `json:"tx_compressed"` // Cumulative count of compressed packets transmitted by the device driver.
+}
+
+// NetDev is parsed from /proc/net/dev or /proc/[pid]/net/dev. The map keys
+// are interface names.
+type NetDev map[string]NetDevLine
+
+// NewNetDev returns kernel/system statistics read from /proc/net/dev.
+func NewNetDev() (NetDev, error) {
+	fs, err := NewFS(DefaultMountPoint)
+	if err != nil {
+		return nil, err
+	}
+
+	return fs.NewNetDev()
+}
+
+// NewNetDev returns kernel/system statistics read from /proc/net/dev.
+func (fs FS) NewNetDev() (NetDev, error) {
+	return newNetDev(fs.Path("net/dev"))
+}
+
+// NewNetDev returns kernel/system statistics read from /proc/[pid]/net/dev.
+func (p Proc) NewNetDev() (NetDev, error) {
+	return newNetDev(p.path("net/dev"))
+}
+
+// newNetDev creates a new NetDev from the contents of the given file.
+func newNetDev(file string) (NetDev, error) {
+	f, err := os.Open(file)
+	if err != nil {
+		return NetDev{}, err
+	}
+	defer f.Close()
+
+	nd := NetDev{}
+	s := bufio.NewScanner(f)
+	for n := 0; s.Scan(); n++ {
+		// Skip the 2 header lines.
+		if n < 2 {
+			continue
+		}
+
+		line, err := nd.parseLine(s.Text())
+		if err != nil {
+			return nd, err
+		}
+
+		nd[line.Name] = *line
+	}
+
+	return nd, s.Err()
+}
+
+// parseLine parses a single line from the /proc/net/dev file. Header lines
+// must be filtered prior to calling this method.
+func (nd NetDev) parseLine(rawLine string) (*NetDevLine, error) {
+	parts := strings.SplitN(rawLine, ":", 2)
+	if len(parts) != 2 {
+		return nil, errors.New("invalid net/dev line, missing colon")
+	}
+	fields := strings.Fields(strings.TrimSpace(parts[1]))
+
+	var err error
+	line := &NetDevLine{}
+
+	// Interface Name
+	line.Name = strings.TrimSpace(parts[0])
+	if line.Name == "" {
+		return nil, errors.New("invalid net/dev line, empty interface name")
+	}
+
+	// RX
+	line.RxBytes, err = strconv.ParseUint(fields[0], 10, 64)
+	if err != nil {
+		return nil, err
+	}
+	line.RxPackets, err = strconv.ParseUint(fields[1], 10, 64)
+	if err != nil {
+		return nil, err
+	}
+	line.RxErrors, err = strconv.ParseUint(fields[2], 10, 64)
+	if err != nil {
+		return nil, err
+	}
+	line.RxDropped, err = strconv.ParseUint(fields[3], 10, 64)
+	if err != nil {
+		return nil, err
+	}
+	line.RxFIFO, err = strconv.ParseUint(fields[4], 10, 64)
+	if err != nil {
+		return nil, err
+	}
+	line.RxFrame, err = strconv.ParseUint(fields[5], 10, 64)
+	if err != nil {
+		return nil, err
+	}
+	line.RxCompressed, err = strconv.ParseUint(fields[6], 10, 64)
+	if err != nil {
+		return nil, err
+	}
+	line.RxMulticast, err = strconv.ParseUint(fields[7], 10, 64)
+	if err != nil {
+		return nil, err
+	}
+
+	// TX
+	line.TxBytes, err = strconv.ParseUint(fields[8], 10, 64)
+	if err != nil {
+		return nil, err
+	}
+	line.TxPackets, err = strconv.ParseUint(fields[9], 10, 64)
+	if err != nil {
+		return nil, err
+	}
+	line.TxErrors, err = strconv.ParseUint(fields[10], 10, 64)
+	if err != nil {
+		return nil, err
+	}
+	line.TxDropped, err = strconv.ParseUint(fields[11], 10, 64)
+	if err != nil {
+		return nil, err
+	}
+	line.TxFIFO, err = strconv.ParseUint(fields[12], 10, 64)
+	if err != nil {
+		return nil, err
+	}
+	line.TxCollisions, err = strconv.ParseUint(fields[13], 10, 64)
+	if err != nil {
+		return nil, err
+	}
+	line.TxCarrier, err = strconv.ParseUint(fields[14], 10, 64)
+	if err != nil {
+		return nil, err
+	}
+	line.TxCompressed, err = strconv.ParseUint(fields[15], 10, 64)
+	if err != nil {
+		return nil, err
+	}
+
+	return line, nil
+}
+
+// Total aggregates the values across interfaces and returns a new NetDevLine.
+// The Name field will be a sorted comma separated list of interface names.
+func (nd NetDev) Total() NetDevLine {
+	total := NetDevLine{}
+
+	names := make([]string, 0, len(nd))
+	for _, ifc := range nd {
+		names = append(names, ifc.Name)
+		total.RxBytes += ifc.RxBytes
+		total.RxPackets += ifc.RxPackets
+		total.RxPackets += ifc.RxPackets
+		total.RxErrors += ifc.RxErrors
+		total.RxDropped += ifc.RxDropped
+		total.RxFIFO += ifc.RxFIFO
+		total.RxFrame += ifc.RxFrame
+		total.RxCompressed += ifc.RxCompressed
+		total.RxMulticast += ifc.RxMulticast
+		total.TxBytes += ifc.TxBytes
+		total.TxPackets += ifc.TxPackets
+		total.TxErrors += ifc.TxErrors
+		total.TxDropped += ifc.TxDropped
+		total.TxFIFO += ifc.TxFIFO
+		total.TxCollisions += ifc.TxCollisions
+		total.TxCarrier += ifc.TxCarrier
+		total.TxCompressed += ifc.TxCompressed
+	}
+	sort.Strings(names)
+	total.Name = strings.Join(names, ", ")
+
+	return total
+}

+ 263 - 0
vendor/github.com/prometheus/procfs/nfs/nfs.go

@@ -0,0 +1,263 @@
+// Copyright 2018 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package nfs implements parsing of /proc/net/rpc/nfsd.
+// Fields are documented in https://www.svennd.be/nfsd-stats-explained-procnetrpcnfsd/
+package nfs
+
+// ReplyCache models the "rc" line.
+type ReplyCache struct {
+	Hits    uint64
+	Misses  uint64
+	NoCache uint64
+}
+
+// FileHandles models the "fh" line.
+type FileHandles struct {
+	Stale        uint64
+	TotalLookups uint64
+	AnonLookups  uint64
+	DirNoCache   uint64
+	NoDirNoCache uint64
+}
+
+// InputOutput models the "io" line.
+type InputOutput struct {
+	Read  uint64
+	Write uint64
+}
+
+// Threads models the "th" line.
+type Threads struct {
+	Threads uint64
+	FullCnt uint64
+}
+
+// ReadAheadCache models the "ra" line.
+type ReadAheadCache struct {
+	CacheSize      uint64
+	CacheHistogram []uint64
+	NotFound       uint64
+}
+
+// Network models the "net" line.
+type Network struct {
+	NetCount   uint64
+	UDPCount   uint64
+	TCPCount   uint64
+	TCPConnect uint64
+}
+
+// ClientRPC models the nfs "rpc" line.
+type ClientRPC struct {
+	RPCCount        uint64
+	Retransmissions uint64
+	AuthRefreshes   uint64
+}
+
+// ServerRPC models the nfsd "rpc" line.
+type ServerRPC struct {
+	RPCCount uint64
+	BadCnt   uint64
+	BadFmt   uint64
+	BadAuth  uint64
+	BadcInt  uint64
+}
+
+// V2Stats models the "proc2" line.
+type V2Stats struct {
+	Null     uint64
+	GetAttr  uint64
+	SetAttr  uint64
+	Root     uint64
+	Lookup   uint64
+	ReadLink uint64
+	Read     uint64
+	WrCache  uint64
+	Write    uint64
+	Create   uint64
+	Remove   uint64
+	Rename   uint64
+	Link     uint64
+	SymLink  uint64
+	MkDir    uint64
+	RmDir    uint64
+	ReadDir  uint64
+	FsStat   uint64
+}
+
+// V3Stats models the "proc3" line.
+type V3Stats struct {
+	Null        uint64
+	GetAttr     uint64
+	SetAttr     uint64
+	Lookup      uint64
+	Access      uint64
+	ReadLink    uint64
+	Read        uint64
+	Write       uint64
+	Create      uint64
+	MkDir       uint64
+	SymLink     uint64
+	MkNod       uint64
+	Remove      uint64
+	RmDir       uint64
+	Rename      uint64
+	Link        uint64
+	ReadDir     uint64
+	ReadDirPlus uint64
+	FsStat      uint64
+	FsInfo      uint64
+	PathConf    uint64
+	Commit      uint64
+}
+
+// ClientV4Stats models the nfs "proc4" line.
+type ClientV4Stats struct {
+	Null               uint64
+	Read               uint64
+	Write              uint64
+	Commit             uint64
+	Open               uint64
+	OpenConfirm        uint64
+	OpenNoattr         uint64
+	OpenDowngrade      uint64
+	Close              uint64
+	Setattr            uint64
+	FsInfo             uint64
+	Renew              uint64
+	SetClientID        uint64
+	SetClientIDConfirm uint64
+	Lock               uint64
+	Lockt              uint64
+	Locku              uint64
+	Access             uint64
+	Getattr            uint64
+	Lookup             uint64
+	LookupRoot         uint64
+	Remove             uint64
+	Rename             uint64
+	Link               uint64
+	Symlink            uint64
+	Create             uint64
+	Pathconf           uint64
+	StatFs             uint64
+	ReadLink           uint64
+	ReadDir            uint64
+	ServerCaps         uint64
+	DelegReturn        uint64
+	GetACL             uint64
+	SetACL             uint64
+	FsLocations        uint64
+	ReleaseLockowner   uint64
+	Secinfo            uint64
+	FsidPresent        uint64
+	ExchangeID         uint64
+	CreateSession      uint64
+	DestroySession     uint64
+	Sequence           uint64
+	GetLeaseTime       uint64
+	ReclaimComplete    uint64
+	LayoutGet          uint64
+	GetDeviceInfo      uint64
+	LayoutCommit       uint64
+	LayoutReturn       uint64
+	SecinfoNoName      uint64
+	TestStateID        uint64
+	FreeStateID        uint64
+	GetDeviceList      uint64
+	BindConnToSession  uint64
+	DestroyClientID    uint64
+	Seek               uint64
+	Allocate           uint64
+	DeAllocate         uint64
+	LayoutStats        uint64
+	Clone              uint64
+}
+
+// ServerV4Stats models the nfsd "proc4" line.
+type ServerV4Stats struct {
+	Null     uint64
+	Compound uint64
+}
+
+// V4Ops models the "proc4ops" line: NFSv4 operations
+// Variable list, see:
+// v4.0 https://tools.ietf.org/html/rfc3010 (38 operations)
+// v4.1 https://tools.ietf.org/html/rfc5661 (58 operations)
+// v4.2 https://tools.ietf.org/html/draft-ietf-nfsv4-minorversion2-41 (71 operations)
+type V4Ops struct {
+	//Values       uint64 // Variable depending on v4.x sub-version. TODO: Will this always at least include the fields in this struct?
+	Op0Unused    uint64
+	Op1Unused    uint64
+	Op2Future    uint64
+	Access       uint64
+	Close        uint64
+	Commit       uint64
+	Create       uint64
+	DelegPurge   uint64
+	DelegReturn  uint64
+	GetAttr      uint64
+	GetFH        uint64
+	Link         uint64
+	Lock         uint64
+	Lockt        uint64
+	Locku        uint64
+	Lookup       uint64
+	LookupRoot   uint64
+	Nverify      uint64
+	Open         uint64
+	OpenAttr     uint64
+	OpenConfirm  uint64
+	OpenDgrd     uint64
+	PutFH        uint64
+	PutPubFH     uint64
+	PutRootFH    uint64
+	Read         uint64
+	ReadDir      uint64
+	ReadLink     uint64
+	Remove       uint64
+	Rename       uint64
+	Renew        uint64
+	RestoreFH    uint64
+	SaveFH       uint64
+	SecInfo      uint64
+	SetAttr      uint64
+	Verify       uint64
+	Write        uint64
+	RelLockOwner uint64
+}
+
+// ClientRPCStats models all stats from /proc/net/rpc/nfs.
+type ClientRPCStats struct {
+	Network       Network
+	ClientRPC     ClientRPC
+	V2Stats       V2Stats
+	V3Stats       V3Stats
+	ClientV4Stats ClientV4Stats
+}
+
+// ServerRPCStats models all stats from /proc/net/rpc/nfsd.
+type ServerRPCStats struct {
+	ReplyCache     ReplyCache
+	FileHandles    FileHandles
+	InputOutput    InputOutput
+	Threads        Threads
+	ReadAheadCache ReadAheadCache
+	Network        Network
+	ServerRPC      ServerRPC
+	V2Stats        V2Stats
+	V3Stats        V3Stats
+	ServerV4Stats  ServerV4Stats
+	V4Ops          V4Ops
+}

+ 317 - 0
vendor/github.com/prometheus/procfs/nfs/parse.go

@@ -0,0 +1,317 @@
+// Copyright 2018 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package nfs
+
+import (
+	"fmt"
+)
+
+func parseReplyCache(v []uint64) (ReplyCache, error) {
+	if len(v) != 3 {
+		return ReplyCache{}, fmt.Errorf("invalid ReplyCache line %q", v)
+	}
+
+	return ReplyCache{
+		Hits:    v[0],
+		Misses:  v[1],
+		NoCache: v[2],
+	}, nil
+}
+
+func parseFileHandles(v []uint64) (FileHandles, error) {
+	if len(v) != 5 {
+		return FileHandles{}, fmt.Errorf("invalid FileHandles, line %q", v)
+	}
+
+	return FileHandles{
+		Stale:        v[0],
+		TotalLookups: v[1],
+		AnonLookups:  v[2],
+		DirNoCache:   v[3],
+		NoDirNoCache: v[4],
+	}, nil
+}
+
+func parseInputOutput(v []uint64) (InputOutput, error) {
+	if len(v) != 2 {
+		return InputOutput{}, fmt.Errorf("invalid InputOutput line %q", v)
+	}
+
+	return InputOutput{
+		Read:  v[0],
+		Write: v[1],
+	}, nil
+}
+
+func parseThreads(v []uint64) (Threads, error) {
+	if len(v) != 2 {
+		return Threads{}, fmt.Errorf("invalid Threads line %q", v)
+	}
+
+	return Threads{
+		Threads: v[0],
+		FullCnt: v[1],
+	}, nil
+}
+
+func parseReadAheadCache(v []uint64) (ReadAheadCache, error) {
+	if len(v) != 12 {
+		return ReadAheadCache{}, fmt.Errorf("invalid ReadAheadCache line %q", v)
+	}
+
+	return ReadAheadCache{
+		CacheSize:      v[0],
+		CacheHistogram: v[1:11],
+		NotFound:       v[11],
+	}, nil
+}
+
+func parseNetwork(v []uint64) (Network, error) {
+	if len(v) != 4 {
+		return Network{}, fmt.Errorf("invalid Network line %q", v)
+	}
+
+	return Network{
+		NetCount:   v[0],
+		UDPCount:   v[1],
+		TCPCount:   v[2],
+		TCPConnect: v[3],
+	}, nil
+}
+
+func parseServerRPC(v []uint64) (ServerRPC, error) {
+	if len(v) != 5 {
+		return ServerRPC{}, fmt.Errorf("invalid RPC line %q", v)
+	}
+
+	return ServerRPC{
+		RPCCount: v[0],
+		BadCnt:   v[1],
+		BadFmt:   v[2],
+		BadAuth:  v[3],
+		BadcInt:  v[4],
+	}, nil
+}
+
+func parseClientRPC(v []uint64) (ClientRPC, error) {
+	if len(v) != 3 {
+		return ClientRPC{}, fmt.Errorf("invalid RPC line %q", v)
+	}
+
+	return ClientRPC{
+		RPCCount:        v[0],
+		Retransmissions: v[1],
+		AuthRefreshes:   v[2],
+	}, nil
+}
+
+func parseV2Stats(v []uint64) (V2Stats, error) {
+	values := int(v[0])
+	if len(v[1:]) != values || values != 18 {
+		return V2Stats{}, fmt.Errorf("invalid V2Stats line %q", v)
+	}
+
+	return V2Stats{
+		Null:     v[1],
+		GetAttr:  v[2],
+		SetAttr:  v[3],
+		Root:     v[4],
+		Lookup:   v[5],
+		ReadLink: v[6],
+		Read:     v[7],
+		WrCache:  v[8],
+		Write:    v[9],
+		Create:   v[10],
+		Remove:   v[11],
+		Rename:   v[12],
+		Link:     v[13],
+		SymLink:  v[14],
+		MkDir:    v[15],
+		RmDir:    v[16],
+		ReadDir:  v[17],
+		FsStat:   v[18],
+	}, nil
+}
+
+func parseV3Stats(v []uint64) (V3Stats, error) {
+	values := int(v[0])
+	if len(v[1:]) != values || values != 22 {
+		return V3Stats{}, fmt.Errorf("invalid V3Stats line %q", v)
+	}
+
+	return V3Stats{
+		Null:        v[1],
+		GetAttr:     v[2],
+		SetAttr:     v[3],
+		Lookup:      v[4],
+		Access:      v[5],
+		ReadLink:    v[6],
+		Read:        v[7],
+		Write:       v[8],
+		Create:      v[9],
+		MkDir:       v[10],
+		SymLink:     v[11],
+		MkNod:       v[12],
+		Remove:      v[13],
+		RmDir:       v[14],
+		Rename:      v[15],
+		Link:        v[16],
+		ReadDir:     v[17],
+		ReadDirPlus: v[18],
+		FsStat:      v[19],
+		FsInfo:      v[20],
+		PathConf:    v[21],
+		Commit:      v[22],
+	}, nil
+}
+
+func parseClientV4Stats(v []uint64) (ClientV4Stats, error) {
+	values := int(v[0])
+	if len(v[1:]) != values {
+		return ClientV4Stats{}, fmt.Errorf("invalid ClientV4Stats line %q", v)
+	}
+
+	// This function currently supports mapping 59 NFS v4 client stats.  Older
+	// kernels may emit fewer stats, so we must detect this and pad out the
+	// values to match the expected slice size.
+	if values < 59 {
+		newValues := make([]uint64, 60)
+		copy(newValues, v)
+		v = newValues
+	}
+
+	return ClientV4Stats{
+		Null:               v[1],
+		Read:               v[2],
+		Write:              v[3],
+		Commit:             v[4],
+		Open:               v[5],
+		OpenConfirm:        v[6],
+		OpenNoattr:         v[7],
+		OpenDowngrade:      v[8],
+		Close:              v[9],
+		Setattr:            v[10],
+		FsInfo:             v[11],
+		Renew:              v[12],
+		SetClientID:        v[13],
+		SetClientIDConfirm: v[14],
+		Lock:               v[15],
+		Lockt:              v[16],
+		Locku:              v[17],
+		Access:             v[18],
+		Getattr:            v[19],
+		Lookup:             v[20],
+		LookupRoot:         v[21],
+		Remove:             v[22],
+		Rename:             v[23],
+		Link:               v[24],
+		Symlink:            v[25],
+		Create:             v[26],
+		Pathconf:           v[27],
+		StatFs:             v[28],
+		ReadLink:           v[29],
+		ReadDir:            v[30],
+		ServerCaps:         v[31],
+		DelegReturn:        v[32],
+		GetACL:             v[33],
+		SetACL:             v[34],
+		FsLocations:        v[35],
+		ReleaseLockowner:   v[36],
+		Secinfo:            v[37],
+		FsidPresent:        v[38],
+		ExchangeID:         v[39],
+		CreateSession:      v[40],
+		DestroySession:     v[41],
+		Sequence:           v[42],
+		GetLeaseTime:       v[43],
+		ReclaimComplete:    v[44],
+		LayoutGet:          v[45],
+		GetDeviceInfo:      v[46],
+		LayoutCommit:       v[47],
+		LayoutReturn:       v[48],
+		SecinfoNoName:      v[49],
+		TestStateID:        v[50],
+		FreeStateID:        v[51],
+		GetDeviceList:      v[52],
+		BindConnToSession:  v[53],
+		DestroyClientID:    v[54],
+		Seek:               v[55],
+		Allocate:           v[56],
+		DeAllocate:         v[57],
+		LayoutStats:        v[58],
+		Clone:              v[59],
+	}, nil
+}
+
+func parseServerV4Stats(v []uint64) (ServerV4Stats, error) {
+	values := int(v[0])
+	if len(v[1:]) != values || values != 2 {
+		return ServerV4Stats{}, fmt.Errorf("invalid V4Stats line %q", v)
+	}
+
+	return ServerV4Stats{
+		Null:     v[1],
+		Compound: v[2],
+	}, nil
+}
+
+func parseV4Ops(v []uint64) (V4Ops, error) {
+	values := int(v[0])
+	if len(v[1:]) != values || values < 39 {
+		return V4Ops{}, fmt.Errorf("invalid V4Ops line %q", v)
+	}
+
+	stats := V4Ops{
+		Op0Unused:    v[1],
+		Op1Unused:    v[2],
+		Op2Future:    v[3],
+		Access:       v[4],
+		Close:        v[5],
+		Commit:       v[6],
+		Create:       v[7],
+		DelegPurge:   v[8],
+		DelegReturn:  v[9],
+		GetAttr:      v[10],
+		GetFH:        v[11],
+		Link:         v[12],
+		Lock:         v[13],
+		Lockt:        v[14],
+		Locku:        v[15],
+		Lookup:       v[16],
+		LookupRoot:   v[17],
+		Nverify:      v[18],
+		Open:         v[19],
+		OpenAttr:     v[20],
+		OpenConfirm:  v[21],
+		OpenDgrd:     v[22],
+		PutFH:        v[23],
+		PutPubFH:     v[24],
+		PutRootFH:    v[25],
+		Read:         v[26],
+		ReadDir:      v[27],
+		ReadLink:     v[28],
+		Remove:       v[29],
+		Rename:       v[30],
+		Renew:        v[31],
+		RestoreFH:    v[32],
+		SaveFH:       v[33],
+		SecInfo:      v[34],
+		SetAttr:      v[35],
+		Verify:       v[36],
+		Write:        v[37],
+		RelLockOwner: v[38],
+	}
+
+	return stats, nil
+}

+ 67 - 0
vendor/github.com/prometheus/procfs/nfs/parse_nfs.go

@@ -0,0 +1,67 @@
+// Copyright 2018 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package nfs
+
+import (
+	"bufio"
+	"fmt"
+	"io"
+	"strings"
+
+	"github.com/prometheus/procfs/internal/util"
+)
+
+// ParseClientRPCStats returns stats read from /proc/net/rpc/nfs
+func ParseClientRPCStats(r io.Reader) (*ClientRPCStats, error) {
+	stats := &ClientRPCStats{}
+
+	scanner := bufio.NewScanner(r)
+	for scanner.Scan() {
+		line := scanner.Text()
+		parts := strings.Fields(scanner.Text())
+		// require at least <key> <value>
+		if len(parts) < 2 {
+			return nil, fmt.Errorf("invalid NFS metric line %q", line)
+		}
+
+		values, err := util.ParseUint64s(parts[1:])
+		if err != nil {
+			return nil, fmt.Errorf("error parsing NFS metric line: %s", err)
+		}
+
+		switch metricLine := parts[0]; metricLine {
+		case "net":
+			stats.Network, err = parseNetwork(values)
+		case "rpc":
+			stats.ClientRPC, err = parseClientRPC(values)
+		case "proc2":
+			stats.V2Stats, err = parseV2Stats(values)
+		case "proc3":
+			stats.V3Stats, err = parseV3Stats(values)
+		case "proc4":
+			stats.ClientV4Stats, err = parseClientV4Stats(values)
+		default:
+			return nil, fmt.Errorf("unknown NFS metric line %q", metricLine)
+		}
+		if err != nil {
+			return nil, fmt.Errorf("errors parsing NFS metric line: %s", err)
+		}
+	}
+
+	if err := scanner.Err(); err != nil {
+		return nil, fmt.Errorf("error scanning NFS file: %s", err)
+	}
+
+	return stats, nil
+}

+ 89 - 0
vendor/github.com/prometheus/procfs/nfs/parse_nfsd.go

@@ -0,0 +1,89 @@
+// Copyright 2018 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package nfs
+
+import (
+	"bufio"
+	"fmt"
+	"io"
+	"strings"
+
+	"github.com/prometheus/procfs/internal/util"
+)
+
+// ParseServerRPCStats returns stats read from /proc/net/rpc/nfsd
+func ParseServerRPCStats(r io.Reader) (*ServerRPCStats, error) {
+	stats := &ServerRPCStats{}
+
+	scanner := bufio.NewScanner(r)
+	for scanner.Scan() {
+		line := scanner.Text()
+		parts := strings.Fields(scanner.Text())
+		// require at least <key> <value>
+		if len(parts) < 2 {
+			return nil, fmt.Errorf("invalid NFSd metric line %q", line)
+		}
+		label := parts[0]
+
+		var values []uint64
+		var err error
+		if label == "th" {
+			if len(parts) < 3 {
+				return nil, fmt.Errorf("invalid NFSd th metric line %q", line)
+			}
+			values, err = util.ParseUint64s(parts[1:3])
+		} else {
+			values, err = util.ParseUint64s(parts[1:])
+		}
+		if err != nil {
+			return nil, fmt.Errorf("error parsing NFSd metric line: %s", err)
+		}
+
+		switch metricLine := parts[0]; metricLine {
+		case "rc":
+			stats.ReplyCache, err = parseReplyCache(values)
+		case "fh":
+			stats.FileHandles, err = parseFileHandles(values)
+		case "io":
+			stats.InputOutput, err = parseInputOutput(values)
+		case "th":
+			stats.Threads, err = parseThreads(values)
+		case "ra":
+			stats.ReadAheadCache, err = parseReadAheadCache(values)
+		case "net":
+			stats.Network, err = parseNetwork(values)
+		case "rpc":
+			stats.ServerRPC, err = parseServerRPC(values)
+		case "proc2":
+			stats.V2Stats, err = parseV2Stats(values)
+		case "proc3":
+			stats.V3Stats, err = parseV3Stats(values)
+		case "proc4":
+			stats.ServerV4Stats, err = parseServerV4Stats(values)
+		case "proc4ops":
+			stats.V4Ops, err = parseV4Ops(values)
+		default:
+			return nil, fmt.Errorf("unknown NFSd metric line %q", metricLine)
+		}
+		if err != nil {
+			return nil, fmt.Errorf("errors parsing NFSd metric line: %s", err)
+		}
+	}
+
+	if err := scanner.Err(); err != nil {
+		return nil, fmt.Errorf("error scanning NFSd file: %s", err)
+	}
+
+	return stats, nil
+}

+ 15 - 1
vendor/github.com/prometheus/procfs/proc.go

@@ -1,6 +1,20 @@
+// Copyright 2018 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package procfs
 package procfs
 
 
 import (
 import (
+	"bytes"
 	"fmt"
 	"fmt"
 	"io/ioutil"
 	"io/ioutil"
 	"os"
 	"os"
@@ -113,7 +127,7 @@ func (p Proc) CmdLine() ([]string, error) {
 		return []string{}, nil
 		return []string{}, nil
 	}
 	}
 
 
-	return strings.Split(string(data[:len(data)-1]), string(byte(0))), nil
+	return strings.Split(string(bytes.TrimRight(data, string("\x00"))), string(byte(0))), nil
 }
 }
 
 
 // Comm returns the command name of a process.
 // Comm returns the command name of a process.

+ 14 - 4
vendor/github.com/prometheus/procfs/proc_io.go

@@ -1,3 +1,16 @@
+// Copyright 2018 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package procfs
 package procfs
 
 
 import (
 import (
@@ -47,9 +60,6 @@ func (p Proc) NewIO() (ProcIO, error) {
 
 
 	_, err = fmt.Sscanf(string(data), ioFormat, &pio.RChar, &pio.WChar, &pio.SyscR,
 	_, err = fmt.Sscanf(string(data), ioFormat, &pio.RChar, &pio.WChar, &pio.SyscR,
 		&pio.SyscW, &pio.ReadBytes, &pio.WriteBytes, &pio.CancelledWriteBytes)
 		&pio.SyscW, &pio.ReadBytes, &pio.WriteBytes, &pio.CancelledWriteBytes)
-	if err != nil {
-		return pio, err
-	}
 
 
-	return pio, nil
+	return pio, err
 }
 }

+ 13 - 0
vendor/github.com/prometheus/procfs/proc_limits.go

@@ -1,3 +1,16 @@
+// Copyright 2018 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package procfs
 package procfs
 
 
 import (
 import (

+ 68 - 0
vendor/github.com/prometheus/procfs/proc_ns.go

@@ -0,0 +1,68 @@
+// Copyright 2018 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package procfs
+
+import (
+	"fmt"
+	"os"
+	"strconv"
+	"strings"
+)
+
+// Namespace represents a single namespace of a process.
+type Namespace struct {
+	Type  string // Namespace type.
+	Inode uint32 // Inode number of the namespace. If two processes are in the same namespace their inodes will match.
+}
+
+// Namespaces contains all of the namespaces that the process is contained in.
+type Namespaces map[string]Namespace
+
+// NewNamespaces reads from /proc/[pid/ns/* to get the namespaces of which the
+// process is a member.
+func (p Proc) NewNamespaces() (Namespaces, error) {
+	d, err := os.Open(p.path("ns"))
+	if err != nil {
+		return nil, err
+	}
+	defer d.Close()
+
+	names, err := d.Readdirnames(-1)
+	if err != nil {
+		return nil, fmt.Errorf("failed to read contents of ns dir: %v", err)
+	}
+
+	ns := make(Namespaces, len(names))
+	for _, name := range names {
+		target, err := os.Readlink(p.path("ns", name))
+		if err != nil {
+			return nil, err
+		}
+
+		fields := strings.SplitN(target, ":", 2)
+		if len(fields) != 2 {
+			return nil, fmt.Errorf("failed to parse namespace type and inode from '%v'", target)
+		}
+
+		typ := fields[0]
+		inode, err := strconv.ParseUint(strings.Trim(fields[1], "[]"), 10, 32)
+		if err != nil {
+			return nil, fmt.Errorf("failed to parse inode from '%v': %v", fields[1], err)
+		}
+
+		ns[name] = Namespace{typ, uint32(inode)}
+	}
+
+	return ns, nil
+}

+ 13 - 0
vendor/github.com/prometheus/procfs/proc_stat.go

@@ -1,3 +1,16 @@
+// Copyright 2018 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package procfs
 package procfs
 
 
 import (
 import (

+ 13 - 0
vendor/github.com/prometheus/procfs/stat.go

@@ -1,3 +1,16 @@
+// Copyright 2018 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 package procfs
 package procfs
 
 
 import (
 import (

+ 4 - 33
vendor/github.com/prometheus/procfs/xfs/parse.go

@@ -17,8 +17,9 @@ import (
 	"bufio"
 	"bufio"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
-	"strconv"
 	"strings"
 	"strings"
+
+	"github.com/prometheus/procfs/internal/util"
 )
 )
 
 
 // ParseStats parses a Stats from an input io.Reader, using the format
 // ParseStats parses a Stats from an input io.Reader, using the format
@@ -68,7 +69,7 @@ func ParseStats(r io.Reader) (*Stats, error) {
 
 
 		// Extended precision counters are uint64 values.
 		// Extended precision counters are uint64 values.
 		if label == fieldXpc {
 		if label == fieldXpc {
-			us, err := parseUint64s(ss[1:])
+			us, err := util.ParseUint64s(ss[1:])
 			if err != nil {
 			if err != nil {
 				return nil, err
 				return nil, err
 			}
 			}
@@ -82,7 +83,7 @@ func ParseStats(r io.Reader) (*Stats, error) {
 		}
 		}
 
 
 		// All other counters are uint32 values.
 		// All other counters are uint32 values.
-		us, err := parseUint32s(ss[1:])
+		us, err := util.ParseUint32s(ss[1:])
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
@@ -327,33 +328,3 @@ func extendedPrecisionStats(us []uint64) (ExtendedPrecisionStats, error) {
 		ReadBytes:  us[2],
 		ReadBytes:  us[2],
 	}, nil
 	}, nil
 }
 }
-
-// parseUint32s parses a slice of strings into a slice of uint32s.
-func parseUint32s(ss []string) ([]uint32, error) {
-	us := make([]uint32, 0, len(ss))
-	for _, s := range ss {
-		u, err := strconv.ParseUint(s, 10, 32)
-		if err != nil {
-			return nil, err
-		}
-
-		us = append(us, uint32(u))
-	}
-
-	return us, nil
-}
-
-// parseUint64s parses a slice of strings into a slice of uint64s.
-func parseUint64s(ss []string) ([]uint64, error) {
-	us := make([]uint64, 0, len(ss))
-	for _, s := range ss {
-		u, err := strconv.ParseUint(s, 10, 64)
-		if err != nil {
-			return nil, err
-		}
-
-		us = append(us, u)
-	}
-
-	return us, nil
-}

+ 29 - 17
vendor/github.com/sirupsen/logrus/entry.go

@@ -94,35 +94,47 @@ func (entry Entry) log(level Level, msg string) {
 	entry.Level = level
 	entry.Level = level
 	entry.Message = msg
 	entry.Message = msg
 
 
-	if err := entry.Logger.Hooks.Fire(level, &entry); err != nil {
-		entry.Logger.mu.Lock()
-		fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
-		entry.Logger.mu.Unlock()
-	}
+	entry.fireHooks()
+
 	buffer = bufferPool.Get().(*bytes.Buffer)
 	buffer = bufferPool.Get().(*bytes.Buffer)
 	buffer.Reset()
 	buffer.Reset()
 	defer bufferPool.Put(buffer)
 	defer bufferPool.Put(buffer)
 	entry.Buffer = buffer
 	entry.Buffer = buffer
-	serialized, err := entry.Logger.Formatter.Format(&entry)
+
+	entry.write()
+
 	entry.Buffer = nil
 	entry.Buffer = nil
+
+	// To avoid Entry#log() returning a value that only would make sense for
+	// panic() to use in Entry#Panic(), we avoid the allocation by checking
+	// directly here.
+	if level <= PanicLevel {
+		panic(&entry)
+	}
+}
+
+// This function is not declared with a pointer value because otherwise
+// race conditions will occur when using multiple goroutines
+func (entry Entry) fireHooks() {
+	entry.Logger.mu.Lock()
+	defer entry.Logger.mu.Unlock()
+	err := entry.Logger.Hooks.Fire(entry.Level, &entry)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
+	}
+}
+
+func (entry *Entry) write() {
+	serialized, err := entry.Logger.Formatter.Format(entry)
+	entry.Logger.mu.Lock()
+	defer entry.Logger.mu.Unlock()
 	if err != nil {
 	if err != nil {
-		entry.Logger.mu.Lock()
 		fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
 		fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
-		entry.Logger.mu.Unlock()
 	} else {
 	} else {
-		entry.Logger.mu.Lock()
 		_, err = entry.Logger.Out.Write(serialized)
 		_, err = entry.Logger.Out.Write(serialized)
 		if err != nil {
 		if err != nil {
 			fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
 			fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
 		}
 		}
-		entry.Logger.mu.Unlock()
-	}
-
-	// To avoid Entry#log() returning a value that only would make sense for
-	// panic() to use in Entry#Panic(), we avoid the allocation by checking
-	// directly here.
-	if level <= PanicLevel {
-		panic(&entry)
 	}
 	}
 }
 }
 
 

+ 6 - 0
vendor/github.com/sirupsen/logrus/logger.go

@@ -315,3 +315,9 @@ func (logger *Logger) level() Level {
 func (logger *Logger) SetLevel(level Level) {
 func (logger *Logger) SetLevel(level Level) {
 	atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
 	atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
 }
 }
+
+func (logger *Logger) AddHook(hook Hook) {
+	logger.mu.Lock()
+	defer logger.mu.Unlock()
+	logger.Hooks.Add(hook)
+}

+ 1 - 1
vendor/github.com/sirupsen/logrus/terminal_bsd.go

@@ -1,5 +1,5 @@
 // +build darwin freebsd openbsd netbsd dragonfly
 // +build darwin freebsd openbsd netbsd dragonfly
-// +build !appengine
+// +build !appengine,!gopherjs
 
 
 package logrus
 package logrus
 
 

+ 11 - 0
vendor/github.com/sirupsen/logrus/terminal_check_appengine.go

@@ -0,0 +1,11 @@
+// +build appengine gopherjs
+
+package logrus
+
+import (
+	"io"
+)
+
+func checkIfTerminal(w io.Writer) bool {
+	return true
+}

+ 19 - 0
vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go

@@ -0,0 +1,19 @@
+// +build !appengine,!gopherjs
+
+package logrus
+
+import (
+	"io"
+	"os"
+
+	"golang.org/x/crypto/ssh/terminal"
+)
+
+func checkIfTerminal(w io.Writer) bool {
+	switch v := w.(type) {
+	case *os.File:
+		return terminal.IsTerminal(int(v.Fd()))
+	default:
+		return false
+	}
+}

+ 1 - 1
vendor/github.com/sirupsen/logrus/terminal_linux.go

@@ -3,7 +3,7 @@
 // Use of this source code is governed by a BSD-style
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-// +build !appengine
+// +build !appengine,!gopherjs
 
 
 package logrus
 package logrus
 
 

+ 1 - 14
vendor/github.com/sirupsen/logrus/text_formatter.go

@@ -3,14 +3,10 @@ package logrus
 import (
 import (
 	"bytes"
 	"bytes"
 	"fmt"
 	"fmt"
-	"io"
-	"os"
 	"sort"
 	"sort"
 	"strings"
 	"strings"
 	"sync"
 	"sync"
 	"time"
 	"time"
-
-	"golang.org/x/crypto/ssh/terminal"
 )
 )
 
 
 const (
 const (
@@ -65,16 +61,7 @@ type TextFormatter struct {
 
 
 func (f *TextFormatter) init(entry *Entry) {
 func (f *TextFormatter) init(entry *Entry) {
 	if entry.Logger != nil {
 	if entry.Logger != nil {
-		f.isTerminal = f.checkIfTerminal(entry.Logger.Out)
-	}
-}
-
-func (f *TextFormatter) checkIfTerminal(w io.Writer) bool {
-	switch v := w.(type) {
-	case *os.File:
-		return terminal.IsTerminal(int(v.Fd()))
-	default:
-		return false
+		f.isTerminal = checkIfTerminal(entry.Logger.Out)
 	}
 	}
 }
 }
 
 

+ 29 - 0
vendor/github.com/spf13/cobra/bash_completions.go

@@ -251,6 +251,14 @@ __%[1]s_handle_word()
         __%[1]s_handle_command
         __%[1]s_handle_command
     elif [[ $c -eq 0 ]]; then
     elif [[ $c -eq 0 ]]; then
         __%[1]s_handle_command
         __%[1]s_handle_command
+    elif __%[1]s_contains_word "${words[c]}" "${command_aliases[@]}"; then
+        # aliashash variable is an associative array which is only supported in bash > 3.
+        if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
+            words[c]=${aliashash[${words[c]}]}
+            __%[1]s_handle_command
+        else
+            __%[1]s_handle_noun
+        fi
     else
     else
         __%[1]s_handle_noun
         __%[1]s_handle_noun
     fi
     fi
@@ -266,6 +274,7 @@ func writePostscript(buf *bytes.Buffer, name string) {
 	buf.WriteString(fmt.Sprintf(`{
 	buf.WriteString(fmt.Sprintf(`{
     local cur prev words cword
     local cur prev words cword
     declare -A flaghash 2>/dev/null || :
     declare -A flaghash 2>/dev/null || :
+    declare -A aliashash 2>/dev/null || :
     if declare -F _init_completion >/dev/null 2>&1; then
     if declare -F _init_completion >/dev/null 2>&1; then
         _init_completion -s || return
         _init_completion -s || return
     else
     else
@@ -305,6 +314,7 @@ func writeCommands(buf *bytes.Buffer, cmd *Command) {
 			continue
 			continue
 		}
 		}
 		buf.WriteString(fmt.Sprintf("    commands+=(%q)\n", c.Name()))
 		buf.WriteString(fmt.Sprintf("    commands+=(%q)\n", c.Name()))
+		writeCmdAliases(buf, c)
 	}
 	}
 	buf.WriteString("\n")
 	buf.WriteString("\n")
 }
 }
@@ -443,6 +453,21 @@ func writeRequiredNouns(buf *bytes.Buffer, cmd *Command) {
 	}
 	}
 }
 }
 
 
+func writeCmdAliases(buf *bytes.Buffer, cmd *Command) {
+	if len(cmd.Aliases) == 0 {
+		return
+	}
+
+	sort.Sort(sort.StringSlice(cmd.Aliases))
+
+	buf.WriteString(fmt.Sprint(`    if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then`, "\n"))
+	for _, value := range cmd.Aliases {
+		buf.WriteString(fmt.Sprintf("        command_aliases+=(%q)\n", value))
+		buf.WriteString(fmt.Sprintf("        aliashash[%q]=%q\n", value, cmd.Name()))
+	}
+	buf.WriteString(`    fi`)
+	buf.WriteString("\n")
+}
 func writeArgAliases(buf *bytes.Buffer, cmd *Command) {
 func writeArgAliases(buf *bytes.Buffer, cmd *Command) {
 	buf.WriteString("    noun_aliases=()\n")
 	buf.WriteString("    noun_aliases=()\n")
 	sort.Sort(sort.StringSlice(cmd.ArgAliases))
 	sort.Sort(sort.StringSlice(cmd.ArgAliases))
@@ -469,6 +494,10 @@ func gen(buf *bytes.Buffer, cmd *Command) {
 	}
 	}
 
 
 	buf.WriteString(fmt.Sprintf("    last_command=%q\n", commandName))
 	buf.WriteString(fmt.Sprintf("    last_command=%q\n", commandName))
+	buf.WriteString("\n")
+	buf.WriteString("    command_aliases=()\n")
+	buf.WriteString("\n")
+
 	writeCommands(buf, cmd)
 	writeCommands(buf, cmd)
 	writeFlags(buf, cmd)
 	writeFlags(buf, cmd)
 	writeRequiredFlag(buf, cmd)
 	writeRequiredFlag(buf, cmd)

+ 8 - 4
vendor/github.com/spf13/pflag/flag.go

@@ -279,16 +279,16 @@ func (f *FlagSet) VisitAll(fn func(*Flag)) {
 	}
 	}
 }
 }
 
 
-// HasFlags returns a bool to indicate if the FlagSet has any flags definied.
+// HasFlags returns a bool to indicate if the FlagSet has any flags defined.
 func (f *FlagSet) HasFlags() bool {
 func (f *FlagSet) HasFlags() bool {
 	return len(f.formal) > 0
 	return len(f.formal) > 0
 }
 }
 
 
 // HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
 // HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
-// definied that are not hidden or deprecated.
+// that are not hidden.
 func (f *FlagSet) HasAvailableFlags() bool {
 func (f *FlagSet) HasAvailableFlags() bool {
 	for _, flag := range f.formal {
 	for _, flag := range f.formal {
-		if !flag.Hidden && len(flag.Deprecated) == 0 {
+		if !flag.Hidden {
 			return true
 			return true
 		}
 		}
 	}
 	}
@@ -398,6 +398,7 @@ func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
 		return fmt.Errorf("deprecated message for flag %q must be set", name)
 		return fmt.Errorf("deprecated message for flag %q must be set", name)
 	}
 	}
 	flag.Deprecated = usageMessage
 	flag.Deprecated = usageMessage
+	flag.Hidden = true
 	return nil
 	return nil
 }
 }
 
 
@@ -668,7 +669,7 @@ func (f *FlagSet) FlagUsagesWrapped(cols int) string {
 
 
 	maxlen := 0
 	maxlen := 0
 	f.VisitAll(func(flag *Flag) {
 	f.VisitAll(func(flag *Flag) {
-		if flag.Deprecated != "" || flag.Hidden {
+		if flag.Hidden {
 			return
 			return
 		}
 		}
 
 
@@ -715,6 +716,9 @@ func (f *FlagSet) FlagUsagesWrapped(cols int) string {
 				line += fmt.Sprintf(" (default %s)", flag.DefValue)
 				line += fmt.Sprintf(" (default %s)", flag.DefValue)
 			}
 			}
 		}
 		}
+		if len(flag.Deprecated) != 0 {
+			line += fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated)
+		}
 
 
 		lines = append(lines, line)
 		lines = append(lines, line)
 	})
 	})

+ 42 - 0
vendor/go.uber.org/atomic/atomic.go

@@ -25,6 +25,7 @@ package atomic
 import (
 import (
 	"math"
 	"math"
 	"sync/atomic"
 	"sync/atomic"
+	"time"
 )
 )
 
 
 // Int32 is an atomic wrapper around an int32.
 // Int32 is an atomic wrapper around an int32.
@@ -304,6 +305,47 @@ func (f *Float64) CAS(old, new float64) bool {
 	return atomic.CompareAndSwapUint64(&f.v, math.Float64bits(old), math.Float64bits(new))
 	return atomic.CompareAndSwapUint64(&f.v, math.Float64bits(old), math.Float64bits(new))
 }
 }
 
 
+// Duration is an atomic wrapper around time.Duration
+// https://godoc.org/time#Duration
+type Duration struct {
+	v Int64
+}
+
+// NewDuration creates a Duration.
+func NewDuration(d time.Duration) *Duration {
+	return &Duration{v: *NewInt64(int64(d))}
+}
+
+// Load atomically loads the wrapped value.
+func (d *Duration) Load() time.Duration {
+	return time.Duration(d.v.Load())
+}
+
+// Store atomically stores the passed value.
+func (d *Duration) Store(n time.Duration) {
+	d.v.Store(int64(n))
+}
+
+// Add atomically adds to the wrapped time.Duration and returns the new value.
+func (d *Duration) Add(n time.Duration) time.Duration {
+	return time.Duration(d.v.Add(int64(n)))
+}
+
+// Sub atomically subtracts from the wrapped time.Duration and returns the new value.
+func (d *Duration) Sub(n time.Duration) time.Duration {
+	return time.Duration(d.v.Sub(int64(n)))
+}
+
+// Swap atomically swaps the wrapped time.Duration and returns the old value.
+func (d *Duration) Swap(n time.Duration) time.Duration {
+	return time.Duration(d.v.Swap(int64(n)))
+}
+
+// CAS is an atomic compare-and-swap.
+func (d *Duration) CAS(old, new time.Duration) bool {
+	return d.v.CAS(int64(old), int64(new))
+}
+
 // Value shadows the type of the same name from sync/atomic
 // Value shadows the type of the same name from sync/atomic
 // https://godoc.org/sync/atomic#Value
 // https://godoc.org/sync/atomic#Value
 type Value struct{ atomic.Value }
 type Value struct{ atomic.Value }

+ 2 - 2
vendor/golang.org/x/crypto/bcrypt/bcrypt.go

@@ -241,11 +241,11 @@ func (p *hashed) Hash() []byte {
 		n = 3
 		n = 3
 	}
 	}
 	arr[n] = '$'
 	arr[n] = '$'
-	n += 1
+	n++
 	copy(arr[n:], []byte(fmt.Sprintf("%02d", p.cost)))
 	copy(arr[n:], []byte(fmt.Sprintf("%02d", p.cost)))
 	n += 2
 	n += 2
 	arr[n] = '$'
 	arr[n] = '$'
-	n += 1
+	n++
 	copy(arr[n:], p.salt)
 	copy(arr[n:], p.salt)
 	n += encodedSaltSize
 	n += encodedSaltSize
 	copy(arr[n:], p.hash)
 	copy(arr[n:], p.hash)

+ 5 - 3
vendor/golang.org/x/crypto/ssh/certs.go

@@ -44,7 +44,9 @@ type Signature struct {
 const CertTimeInfinity = 1<<64 - 1
 const CertTimeInfinity = 1<<64 - 1
 
 
 // An Certificate represents an OpenSSH certificate as defined in
 // An Certificate represents an OpenSSH certificate as defined in
-// [PROTOCOL.certkeys]?rev=1.8.
+// [PROTOCOL.certkeys]?rev=1.8. The Certificate type implements the
+// PublicKey interface, so it can be unmarshaled using
+// ParsePublicKey.
 type Certificate struct {
 type Certificate struct {
 	Nonce           []byte
 	Nonce           []byte
 	Key             PublicKey
 	Key             PublicKey
@@ -340,10 +342,10 @@ func (c *CertChecker) Authenticate(conn ConnMetadata, pubKey PublicKey) (*Permis
 // the signature of the certificate.
 // the signature of the certificate.
 func (c *CertChecker) CheckCert(principal string, cert *Certificate) error {
 func (c *CertChecker) CheckCert(principal string, cert *Certificate) error {
 	if c.IsRevoked != nil && c.IsRevoked(cert) {
 	if c.IsRevoked != nil && c.IsRevoked(cert) {
-		return fmt.Errorf("ssh: certicate serial %d revoked", cert.Serial)
+		return fmt.Errorf("ssh: certificate serial %d revoked", cert.Serial)
 	}
 	}
 
 
-	for opt, _ := range cert.CriticalOptions {
+	for opt := range cert.CriticalOptions {
 		// sourceAddressCriticalOption will be enforced by
 		// sourceAddressCriticalOption will be enforced by
 		// serverAuthenticate
 		// serverAuthenticate
 		if opt == sourceAddressCriticalOption {
 		if opt == sourceAddressCriticalOption {

+ 71 - 71
vendor/golang.org/x/crypto/ssh/channel.go

@@ -205,32 +205,32 @@ type channel struct {
 
 
 // writePacket sends a packet. If the packet is a channel close, it updates
 // writePacket sends a packet. If the packet is a channel close, it updates
 // sentClose. This method takes the lock c.writeMu.
 // sentClose. This method takes the lock c.writeMu.
-func (c *channel) writePacket(packet []byte) error {
-	c.writeMu.Lock()
-	if c.sentClose {
-		c.writeMu.Unlock()
+func (ch *channel) writePacket(packet []byte) error {
+	ch.writeMu.Lock()
+	if ch.sentClose {
+		ch.writeMu.Unlock()
 		return io.EOF
 		return io.EOF
 	}
 	}
-	c.sentClose = (packet[0] == msgChannelClose)
-	err := c.mux.conn.writePacket(packet)
-	c.writeMu.Unlock()
+	ch.sentClose = (packet[0] == msgChannelClose)
+	err := ch.mux.conn.writePacket(packet)
+	ch.writeMu.Unlock()
 	return err
 	return err
 }
 }
 
 
-func (c *channel) sendMessage(msg interface{}) error {
+func (ch *channel) sendMessage(msg interface{}) error {
 	if debugMux {
 	if debugMux {
-		log.Printf("send(%d): %#v", c.mux.chanList.offset, msg)
+		log.Printf("send(%d): %#v", ch.mux.chanList.offset, msg)
 	}
 	}
 
 
 	p := Marshal(msg)
 	p := Marshal(msg)
-	binary.BigEndian.PutUint32(p[1:], c.remoteId)
-	return c.writePacket(p)
+	binary.BigEndian.PutUint32(p[1:], ch.remoteId)
+	return ch.writePacket(p)
 }
 }
 
 
 // WriteExtended writes data to a specific extended stream. These streams are
 // WriteExtended writes data to a specific extended stream. These streams are
 // used, for example, for stderr.
 // used, for example, for stderr.
-func (c *channel) WriteExtended(data []byte, extendedCode uint32) (n int, err error) {
-	if c.sentEOF {
+func (ch *channel) WriteExtended(data []byte, extendedCode uint32) (n int, err error) {
+	if ch.sentEOF {
 		return 0, io.EOF
 		return 0, io.EOF
 	}
 	}
 	// 1 byte message type, 4 bytes remoteId, 4 bytes data length
 	// 1 byte message type, 4 bytes remoteId, 4 bytes data length
@@ -241,16 +241,16 @@ func (c *channel) WriteExtended(data []byte, extendedCode uint32) (n int, err er
 		opCode = msgChannelExtendedData
 		opCode = msgChannelExtendedData
 	}
 	}
 
 
-	c.writeMu.Lock()
-	packet := c.packetPool[extendedCode]
+	ch.writeMu.Lock()
+	packet := ch.packetPool[extendedCode]
 	// We don't remove the buffer from packetPool, so
 	// We don't remove the buffer from packetPool, so
 	// WriteExtended calls from different goroutines will be
 	// WriteExtended calls from different goroutines will be
 	// flagged as errors by the race detector.
 	// flagged as errors by the race detector.
-	c.writeMu.Unlock()
+	ch.writeMu.Unlock()
 
 
 	for len(data) > 0 {
 	for len(data) > 0 {
-		space := min(c.maxRemotePayload, len(data))
-		if space, err = c.remoteWin.reserve(space); err != nil {
+		space := min(ch.maxRemotePayload, len(data))
+		if space, err = ch.remoteWin.reserve(space); err != nil {
 			return n, err
 			return n, err
 		}
 		}
 		if want := headerLength + space; uint32(cap(packet)) < want {
 		if want := headerLength + space; uint32(cap(packet)) < want {
@@ -262,13 +262,13 @@ func (c *channel) WriteExtended(data []byte, extendedCode uint32) (n int, err er
 		todo := data[:space]
 		todo := data[:space]
 
 
 		packet[0] = opCode
 		packet[0] = opCode
-		binary.BigEndian.PutUint32(packet[1:], c.remoteId)
+		binary.BigEndian.PutUint32(packet[1:], ch.remoteId)
 		if extendedCode > 0 {
 		if extendedCode > 0 {
 			binary.BigEndian.PutUint32(packet[5:], uint32(extendedCode))
 			binary.BigEndian.PutUint32(packet[5:], uint32(extendedCode))
 		}
 		}
 		binary.BigEndian.PutUint32(packet[headerLength-4:], uint32(len(todo)))
 		binary.BigEndian.PutUint32(packet[headerLength-4:], uint32(len(todo)))
 		copy(packet[headerLength:], todo)
 		copy(packet[headerLength:], todo)
-		if err = c.writePacket(packet); err != nil {
+		if err = ch.writePacket(packet); err != nil {
 			return n, err
 			return n, err
 		}
 		}
 
 
@@ -276,14 +276,14 @@ func (c *channel) WriteExtended(data []byte, extendedCode uint32) (n int, err er
 		data = data[len(todo):]
 		data = data[len(todo):]
 	}
 	}
 
 
-	c.writeMu.Lock()
-	c.packetPool[extendedCode] = packet
-	c.writeMu.Unlock()
+	ch.writeMu.Lock()
+	ch.packetPool[extendedCode] = packet
+	ch.writeMu.Unlock()
 
 
 	return n, err
 	return n, err
 }
 }
 
 
-func (c *channel) handleData(packet []byte) error {
+func (ch *channel) handleData(packet []byte) error {
 	headerLen := 9
 	headerLen := 9
 	isExtendedData := packet[0] == msgChannelExtendedData
 	isExtendedData := packet[0] == msgChannelExtendedData
 	if isExtendedData {
 	if isExtendedData {
@@ -303,7 +303,7 @@ func (c *channel) handleData(packet []byte) error {
 	if length == 0 {
 	if length == 0 {
 		return nil
 		return nil
 	}
 	}
-	if length > c.maxIncomingPayload {
+	if length > ch.maxIncomingPayload {
 		// TODO(hanwen): should send Disconnect?
 		// TODO(hanwen): should send Disconnect?
 		return errors.New("ssh: incoming packet exceeds maximum payload size")
 		return errors.New("ssh: incoming packet exceeds maximum payload size")
 	}
 	}
@@ -313,21 +313,21 @@ func (c *channel) handleData(packet []byte) error {
 		return errors.New("ssh: wrong packet length")
 		return errors.New("ssh: wrong packet length")
 	}
 	}
 
 
-	c.windowMu.Lock()
-	if c.myWindow < length {
-		c.windowMu.Unlock()
+	ch.windowMu.Lock()
+	if ch.myWindow < length {
+		ch.windowMu.Unlock()
 		// TODO(hanwen): should send Disconnect with reason?
 		// TODO(hanwen): should send Disconnect with reason?
 		return errors.New("ssh: remote side wrote too much")
 		return errors.New("ssh: remote side wrote too much")
 	}
 	}
-	c.myWindow -= length
-	c.windowMu.Unlock()
+	ch.myWindow -= length
+	ch.windowMu.Unlock()
 
 
 	if extended == 1 {
 	if extended == 1 {
-		c.extPending.write(data)
+		ch.extPending.write(data)
 	} else if extended > 0 {
 	} else if extended > 0 {
 		// discard other extended data.
 		// discard other extended data.
 	} else {
 	} else {
-		c.pending.write(data)
+		ch.pending.write(data)
 	}
 	}
 	return nil
 	return nil
 }
 }
@@ -384,31 +384,31 @@ func (c *channel) close() {
 // responseMessageReceived is called when a success or failure message is
 // responseMessageReceived is called when a success or failure message is
 // received on a channel to check that such a message is reasonable for the
 // received on a channel to check that such a message is reasonable for the
 // given channel.
 // given channel.
-func (c *channel) responseMessageReceived() error {
-	if c.direction == channelInbound {
+func (ch *channel) responseMessageReceived() error {
+	if ch.direction == channelInbound {
 		return errors.New("ssh: channel response message received on inbound channel")
 		return errors.New("ssh: channel response message received on inbound channel")
 	}
 	}
-	if c.decided {
+	if ch.decided {
 		return errors.New("ssh: duplicate response received for channel")
 		return errors.New("ssh: duplicate response received for channel")
 	}
 	}
-	c.decided = true
+	ch.decided = true
 	return nil
 	return nil
 }
 }
 
 
-func (c *channel) handlePacket(packet []byte) error {
+func (ch *channel) handlePacket(packet []byte) error {
 	switch packet[0] {
 	switch packet[0] {
 	case msgChannelData, msgChannelExtendedData:
 	case msgChannelData, msgChannelExtendedData:
-		return c.handleData(packet)
+		return ch.handleData(packet)
 	case msgChannelClose:
 	case msgChannelClose:
-		c.sendMessage(channelCloseMsg{PeersId: c.remoteId})
-		c.mux.chanList.remove(c.localId)
-		c.close()
+		ch.sendMessage(channelCloseMsg{PeersID: ch.remoteId})
+		ch.mux.chanList.remove(ch.localId)
+		ch.close()
 		return nil
 		return nil
 	case msgChannelEOF:
 	case msgChannelEOF:
 		// RFC 4254 is mute on how EOF affects dataExt messages but
 		// RFC 4254 is mute on how EOF affects dataExt messages but
 		// it is logical to signal EOF at the same time.
 		// it is logical to signal EOF at the same time.
-		c.extPending.eof()
-		c.pending.eof()
+		ch.extPending.eof()
+		ch.pending.eof()
 		return nil
 		return nil
 	}
 	}
 
 
@@ -419,24 +419,24 @@ func (c *channel) handlePacket(packet []byte) error {
 
 
 	switch msg := decoded.(type) {
 	switch msg := decoded.(type) {
 	case *channelOpenFailureMsg:
 	case *channelOpenFailureMsg:
-		if err := c.responseMessageReceived(); err != nil {
+		if err := ch.responseMessageReceived(); err != nil {
 			return err
 			return err
 		}
 		}
-		c.mux.chanList.remove(msg.PeersId)
-		c.msg <- msg
+		ch.mux.chanList.remove(msg.PeersID)
+		ch.msg <- msg
 	case *channelOpenConfirmMsg:
 	case *channelOpenConfirmMsg:
-		if err := c.responseMessageReceived(); err != nil {
+		if err := ch.responseMessageReceived(); err != nil {
 			return err
 			return err
 		}
 		}
 		if msg.MaxPacketSize < minPacketLength || msg.MaxPacketSize > 1<<31 {
 		if msg.MaxPacketSize < minPacketLength || msg.MaxPacketSize > 1<<31 {
 			return fmt.Errorf("ssh: invalid MaxPacketSize %d from peer", msg.MaxPacketSize)
 			return fmt.Errorf("ssh: invalid MaxPacketSize %d from peer", msg.MaxPacketSize)
 		}
 		}
-		c.remoteId = msg.MyId
-		c.maxRemotePayload = msg.MaxPacketSize
-		c.remoteWin.add(msg.MyWindow)
-		c.msg <- msg
+		ch.remoteId = msg.MyID
+		ch.maxRemotePayload = msg.MaxPacketSize
+		ch.remoteWin.add(msg.MyWindow)
+		ch.msg <- msg
 	case *windowAdjustMsg:
 	case *windowAdjustMsg:
-		if !c.remoteWin.add(msg.AdditionalBytes) {
+		if !ch.remoteWin.add(msg.AdditionalBytes) {
 			return fmt.Errorf("ssh: invalid window update for %d bytes", msg.AdditionalBytes)
 			return fmt.Errorf("ssh: invalid window update for %d bytes", msg.AdditionalBytes)
 		}
 		}
 	case *channelRequestMsg:
 	case *channelRequestMsg:
@@ -444,12 +444,12 @@ func (c *channel) handlePacket(packet []byte) error {
 			Type:      msg.Request,
 			Type:      msg.Request,
 			WantReply: msg.WantReply,
 			WantReply: msg.WantReply,
 			Payload:   msg.RequestSpecificData,
 			Payload:   msg.RequestSpecificData,
-			ch:        c,
+			ch:        ch,
 		}
 		}
 
 
-		c.incomingRequests <- &req
+		ch.incomingRequests <- &req
 	default:
 	default:
-		c.msg <- msg
+		ch.msg <- msg
 	}
 	}
 	return nil
 	return nil
 }
 }
@@ -488,23 +488,23 @@ func (e *extChannel) Read(data []byte) (n int, err error) {
 	return e.ch.ReadExtended(data, e.code)
 	return e.ch.ReadExtended(data, e.code)
 }
 }
 
 
-func (c *channel) Accept() (Channel, <-chan *Request, error) {
-	if c.decided {
+func (ch *channel) Accept() (Channel, <-chan *Request, error) {
+	if ch.decided {
 		return nil, nil, errDecidedAlready
 		return nil, nil, errDecidedAlready
 	}
 	}
-	c.maxIncomingPayload = channelMaxPacket
+	ch.maxIncomingPayload = channelMaxPacket
 	confirm := channelOpenConfirmMsg{
 	confirm := channelOpenConfirmMsg{
-		PeersId:       c.remoteId,
-		MyId:          c.localId,
-		MyWindow:      c.myWindow,
-		MaxPacketSize: c.maxIncomingPayload,
+		PeersID:       ch.remoteId,
+		MyID:          ch.localId,
+		MyWindow:      ch.myWindow,
+		MaxPacketSize: ch.maxIncomingPayload,
 	}
 	}
-	c.decided = true
-	if err := c.sendMessage(confirm); err != nil {
+	ch.decided = true
+	if err := ch.sendMessage(confirm); err != nil {
 		return nil, nil, err
 		return nil, nil, err
 	}
 	}
 
 
-	return c, c.incomingRequests, nil
+	return ch, ch.incomingRequests, nil
 }
 }
 
 
 func (ch *channel) Reject(reason RejectionReason, message string) error {
 func (ch *channel) Reject(reason RejectionReason, message string) error {
@@ -512,7 +512,7 @@ func (ch *channel) Reject(reason RejectionReason, message string) error {
 		return errDecidedAlready
 		return errDecidedAlready
 	}
 	}
 	reject := channelOpenFailureMsg{
 	reject := channelOpenFailureMsg{
-		PeersId:  ch.remoteId,
+		PeersID:  ch.remoteId,
 		Reason:   reason,
 		Reason:   reason,
 		Message:  message,
 		Message:  message,
 		Language: "en",
 		Language: "en",
@@ -541,7 +541,7 @@ func (ch *channel) CloseWrite() error {
 	}
 	}
 	ch.sentEOF = true
 	ch.sentEOF = true
 	return ch.sendMessage(channelEOFMsg{
 	return ch.sendMessage(channelEOFMsg{
-		PeersId: ch.remoteId})
+		PeersID: ch.remoteId})
 }
 }
 
 
 func (ch *channel) Close() error {
 func (ch *channel) Close() error {
@@ -550,7 +550,7 @@ func (ch *channel) Close() error {
 	}
 	}
 
 
 	return ch.sendMessage(channelCloseMsg{
 	return ch.sendMessage(channelCloseMsg{
-		PeersId: ch.remoteId})
+		PeersID: ch.remoteId})
 }
 }
 
 
 // Extended returns an io.ReadWriter that sends and receives data on the given,
 // Extended returns an io.ReadWriter that sends and receives data on the given,
@@ -577,7 +577,7 @@ func (ch *channel) SendRequest(name string, wantReply bool, payload []byte) (boo
 	}
 	}
 
 
 	msg := channelRequestMsg{
 	msg := channelRequestMsg{
-		PeersId:             ch.remoteId,
+		PeersID:             ch.remoteId,
 		Request:             name,
 		Request:             name,
 		WantReply:           wantReply,
 		WantReply:           wantReply,
 		RequestSpecificData: payload,
 		RequestSpecificData: payload,
@@ -614,11 +614,11 @@ func (ch *channel) ackRequest(ok bool) error {
 	var msg interface{}
 	var msg interface{}
 	if !ok {
 	if !ok {
 		msg = channelRequestFailureMsg{
 		msg = channelRequestFailureMsg{
-			PeersId: ch.remoteId,
+			PeersID: ch.remoteId,
 		}
 		}
 	} else {
 	} else {
 		msg = channelRequestSuccessMsg{
 		msg = channelRequestSuccessMsg{
-			PeersId: ch.remoteId,
+			PeersID: ch.remoteId,
 		}
 		}
 	}
 	}
 	return ch.sendMessage(msg)
 	return ch.sendMessage(msg)

+ 194 - 53
vendor/golang.org/x/crypto/ssh/cipher.go

@@ -16,6 +16,10 @@ import (
 	"hash"
 	"hash"
 	"io"
 	"io"
 	"io/ioutil"
 	"io/ioutil"
+	"math/bits"
+
+	"golang.org/x/crypto/internal/chacha20"
+	"golang.org/x/crypto/poly1305"
 )
 )
 
 
 const (
 const (
@@ -53,78 +57,78 @@ func newRC4(key, iv []byte) (cipher.Stream, error) {
 	return rc4.NewCipher(key)
 	return rc4.NewCipher(key)
 }
 }
 
 
-type streamCipherMode struct {
-	keySize    int
-	ivSize     int
-	skip       int
-	createFunc func(key, iv []byte) (cipher.Stream, error)
+type cipherMode struct {
+	keySize int
+	ivSize  int
+	create  func(key, iv []byte, macKey []byte, algs directionAlgorithms) (packetCipher, error)
 }
 }
 
 
-func (c *streamCipherMode) createStream(key, iv []byte) (cipher.Stream, error) {
-	if len(key) < c.keySize {
-		panic("ssh: key length too small for cipher")
-	}
-	if len(iv) < c.ivSize {
-		panic("ssh: iv too small for cipher")
-	}
-
-	stream, err := c.createFunc(key[:c.keySize], iv[:c.ivSize])
-	if err != nil {
-		return nil, err
-	}
+func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream, error)) func(key, iv []byte, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
+	return func(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
+		stream, err := createFunc(key, iv)
+		if err != nil {
+			return nil, err
+		}
 
 
-	var streamDump []byte
-	if c.skip > 0 {
-		streamDump = make([]byte, 512)
-	}
+		var streamDump []byte
+		if skip > 0 {
+			streamDump = make([]byte, 512)
+		}
 
 
-	for remainingToDump := c.skip; remainingToDump > 0; {
-		dumpThisTime := remainingToDump
-		if dumpThisTime > len(streamDump) {
-			dumpThisTime = len(streamDump)
+		for remainingToDump := skip; remainingToDump > 0; {
+			dumpThisTime := remainingToDump
+			if dumpThisTime > len(streamDump) {
+				dumpThisTime = len(streamDump)
+			}
+			stream.XORKeyStream(streamDump[:dumpThisTime], streamDump[:dumpThisTime])
+			remainingToDump -= dumpThisTime
 		}
 		}
-		stream.XORKeyStream(streamDump[:dumpThisTime], streamDump[:dumpThisTime])
-		remainingToDump -= dumpThisTime
-	}
 
 
-	return stream, nil
+		mac := macModes[algs.MAC].new(macKey)
+		return &streamPacketCipher{
+			mac:       mac,
+			etm:       macModes[algs.MAC].etm,
+			macResult: make([]byte, mac.Size()),
+			cipher:    stream,
+		}, nil
+	}
 }
 }
 
 
 // cipherModes documents properties of supported ciphers. Ciphers not included
 // cipherModes documents properties of supported ciphers. Ciphers not included
 // are not supported and will not be negotiated, even if explicitly requested in
 // are not supported and will not be negotiated, even if explicitly requested in
 // ClientConfig.Crypto.Ciphers.
 // ClientConfig.Crypto.Ciphers.
-var cipherModes = map[string]*streamCipherMode{
+var cipherModes = map[string]*cipherMode{
 	// Ciphers from RFC4344, which introduced many CTR-based ciphers. Algorithms
 	// Ciphers from RFC4344, which introduced many CTR-based ciphers. Algorithms
 	// are defined in the order specified in the RFC.
 	// are defined in the order specified in the RFC.
-	"aes128-ctr": {16, aes.BlockSize, 0, newAESCTR},
-	"aes192-ctr": {24, aes.BlockSize, 0, newAESCTR},
-	"aes256-ctr": {32, aes.BlockSize, 0, newAESCTR},
+	"aes128-ctr": {16, aes.BlockSize, streamCipherMode(0, newAESCTR)},
+	"aes192-ctr": {24, aes.BlockSize, streamCipherMode(0, newAESCTR)},
+	"aes256-ctr": {32, aes.BlockSize, streamCipherMode(0, newAESCTR)},
 
 
 	// Ciphers from RFC4345, which introduces security-improved arcfour ciphers.
 	// Ciphers from RFC4345, which introduces security-improved arcfour ciphers.
 	// They are defined in the order specified in the RFC.
 	// They are defined in the order specified in the RFC.
-	"arcfour128": {16, 0, 1536, newRC4},
-	"arcfour256": {32, 0, 1536, newRC4},
+	"arcfour128": {16, 0, streamCipherMode(1536, newRC4)},
+	"arcfour256": {32, 0, streamCipherMode(1536, newRC4)},
 
 
 	// Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol.
 	// Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol.
 	// Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and
 	// Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and
 	// RC4) has problems with weak keys, and should be used with caution."
 	// RC4) has problems with weak keys, and should be used with caution."
 	// RFC4345 introduces improved versions of Arcfour.
 	// RFC4345 introduces improved versions of Arcfour.
-	"arcfour": {16, 0, 0, newRC4},
+	"arcfour": {16, 0, streamCipherMode(0, newRC4)},
 
 
-	// AES-GCM is not a stream cipher, so it is constructed with a
-	// special case. If we add any more non-stream ciphers, we
-	// should invest a cleaner way to do this.
-	gcmCipherID: {16, 12, 0, nil},
+	// AEAD ciphers
+	gcmCipherID:        {16, 12, newGCMCipher},
+	chacha20Poly1305ID: {64, 0, newChaCha20Cipher},
 
 
 	// CBC mode is insecure and so is not included in the default config.
 	// CBC mode is insecure and so is not included in the default config.
 	// (See http://www.isg.rhul.ac.uk/~kp/SandPfinal.pdf). If absolutely
 	// (See http://www.isg.rhul.ac.uk/~kp/SandPfinal.pdf). If absolutely
 	// needed, it's possible to specify a custom Config to enable it.
 	// needed, it's possible to specify a custom Config to enable it.
 	// You should expect that an active attacker can recover plaintext if
 	// You should expect that an active attacker can recover plaintext if
 	// you do.
 	// you do.
-	aes128cbcID: {16, aes.BlockSize, 0, nil},
+	aes128cbcID: {16, aes.BlockSize, newAESCBCCipher},
 
 
-	// 3des-cbc is insecure and is disabled by default.
-	tripledescbcID: {24, des.BlockSize, 0, nil},
+	// 3des-cbc is insecure and is not included in the default
+	// config.
+	tripledescbcID: {24, des.BlockSize, newTripleDESCBCCipher},
 }
 }
 
 
 // prefixLen is the length of the packet prefix that contains the packet length
 // prefixLen is the length of the packet prefix that contains the packet length
@@ -304,7 +308,7 @@ type gcmCipher struct {
 	buf    []byte
 	buf    []byte
 }
 }
 
 
-func newGCMCipher(iv, key, macKey []byte) (packetCipher, error) {
+func newGCMCipher(key, iv, unusedMacKey []byte, unusedAlgs directionAlgorithms) (packetCipher, error) {
 	c, err := aes.NewCipher(key)
 	c, err := aes.NewCipher(key)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -372,7 +376,7 @@ func (c *gcmCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
 	}
 	}
 	length := binary.BigEndian.Uint32(c.prefix[:])
 	length := binary.BigEndian.Uint32(c.prefix[:])
 	if length > maxPacket {
 	if length > maxPacket {
-		return nil, errors.New("ssh: max packet length exceeded.")
+		return nil, errors.New("ssh: max packet length exceeded")
 	}
 	}
 
 
 	if cap(c.buf) < int(length+gcmTagSize) {
 	if cap(c.buf) < int(length+gcmTagSize) {
@@ -422,7 +426,7 @@ type cbcCipher struct {
 	oracleCamouflage uint32
 	oracleCamouflage uint32
 }
 }
 
 
-func newCBCCipher(c cipher.Block, iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
+func newCBCCipher(c cipher.Block, key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
 	cbc := &cbcCipher{
 	cbc := &cbcCipher{
 		mac:        macModes[algs.MAC].new(macKey),
 		mac:        macModes[algs.MAC].new(macKey),
 		decrypter:  cipher.NewCBCDecrypter(c, iv),
 		decrypter:  cipher.NewCBCDecrypter(c, iv),
@@ -436,13 +440,13 @@ func newCBCCipher(c cipher.Block, iv, key, macKey []byte, algs directionAlgorith
 	return cbc, nil
 	return cbc, nil
 }
 }
 
 
-func newAESCBCCipher(iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
+func newAESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
 	c, err := aes.NewCipher(key)
 	c, err := aes.NewCipher(key)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	cbc, err := newCBCCipher(c, iv, key, macKey, algs)
+	cbc, err := newCBCCipher(c, key, iv, macKey, algs)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -450,13 +454,13 @@ func newAESCBCCipher(iv, key, macKey []byte, algs directionAlgorithms) (packetCi
 	return cbc, nil
 	return cbc, nil
 }
 }
 
 
-func newTripleDESCBCCipher(iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
+func newTripleDESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
 	c, err := des.NewTripleDESCipher(key)
 	c, err := des.NewTripleDESCipher(key)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	cbc, err := newCBCCipher(c, iv, key, macKey, algs)
+	cbc, err := newCBCCipher(c, key, iv, macKey, algs)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -548,11 +552,11 @@ func (c *cbcCipher) readPacketLeaky(seqNum uint32, r io.Reader) ([]byte, error)
 		c.packetData = c.packetData[:entirePacketSize]
 		c.packetData = c.packetData[:entirePacketSize]
 	}
 	}
 
 
-	if n, err := io.ReadFull(r, c.packetData[firstBlockLength:]); err != nil {
+	n, err := io.ReadFull(r, c.packetData[firstBlockLength:])
+	if err != nil {
 		return nil, err
 		return nil, err
-	} else {
-		c.oracleCamouflage -= uint32(n)
 	}
 	}
+	c.oracleCamouflage -= uint32(n)
 
 
 	remainingCrypted := c.packetData[firstBlockLength:macStart]
 	remainingCrypted := c.packetData[firstBlockLength:macStart]
 	c.decrypter.CryptBlocks(remainingCrypted, remainingCrypted)
 	c.decrypter.CryptBlocks(remainingCrypted, remainingCrypted)
@@ -627,3 +631,140 @@ func (c *cbcCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, pack
 
 
 	return nil
 	return nil
 }
 }
+
+const chacha20Poly1305ID = "chacha20-poly1305@openssh.com"
+
+// chacha20Poly1305Cipher implements the chacha20-poly1305@openssh.com
+// AEAD, which is described here:
+//
+//   https://tools.ietf.org/html/draft-josefsson-ssh-chacha20-poly1305-openssh-00
+//
+// the methods here also implement padding, which RFC4253 Section 6
+// also requires of stream ciphers.
+type chacha20Poly1305Cipher struct {
+	lengthKey  [8]uint32
+	contentKey [8]uint32
+	buf        []byte
+}
+
+func newChaCha20Cipher(key, unusedIV, unusedMACKey []byte, unusedAlgs directionAlgorithms) (packetCipher, error) {
+	if len(key) != 64 {
+		panic(len(key))
+	}
+
+	c := &chacha20Poly1305Cipher{
+		buf: make([]byte, 256),
+	}
+
+	for i := range c.contentKey {
+		c.contentKey[i] = binary.LittleEndian.Uint32(key[i*4 : (i+1)*4])
+	}
+	for i := range c.lengthKey {
+		c.lengthKey[i] = binary.LittleEndian.Uint32(key[(i+8)*4 : (i+9)*4])
+	}
+	return c, nil
+}
+
+func (c *chacha20Poly1305Cipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
+	nonce := [3]uint32{0, 0, bits.ReverseBytes32(seqNum)}
+	s := chacha20.New(c.contentKey, nonce)
+	var polyKey [32]byte
+	s.XORKeyStream(polyKey[:], polyKey[:])
+	s.Advance() // skip next 32 bytes
+
+	encryptedLength := c.buf[:4]
+	if _, err := io.ReadFull(r, encryptedLength); err != nil {
+		return nil, err
+	}
+
+	var lenBytes [4]byte
+	chacha20.New(c.lengthKey, nonce).XORKeyStream(lenBytes[:], encryptedLength)
+
+	length := binary.BigEndian.Uint32(lenBytes[:])
+	if length > maxPacket {
+		return nil, errors.New("ssh: invalid packet length, packet too large")
+	}
+
+	contentEnd := 4 + length
+	packetEnd := contentEnd + poly1305.TagSize
+	if uint32(cap(c.buf)) < packetEnd {
+		c.buf = make([]byte, packetEnd)
+		copy(c.buf[:], encryptedLength)
+	} else {
+		c.buf = c.buf[:packetEnd]
+	}
+
+	if _, err := io.ReadFull(r, c.buf[4:packetEnd]); err != nil {
+		return nil, err
+	}
+
+	var mac [poly1305.TagSize]byte
+	copy(mac[:], c.buf[contentEnd:packetEnd])
+	if !poly1305.Verify(&mac, c.buf[:contentEnd], &polyKey) {
+		return nil, errors.New("ssh: MAC failure")
+	}
+
+	plain := c.buf[4:contentEnd]
+	s.XORKeyStream(plain, plain)
+
+	padding := plain[0]
+	if padding < 4 {
+		// padding is a byte, so it automatically satisfies
+		// the maximum size, which is 255.
+		return nil, fmt.Errorf("ssh: illegal padding %d", padding)
+	}
+
+	if int(padding)+1 >= len(plain) {
+		return nil, fmt.Errorf("ssh: padding %d too large", padding)
+	}
+
+	plain = plain[1 : len(plain)-int(padding)]
+
+	return plain, nil
+}
+
+func (c *chacha20Poly1305Cipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, payload []byte) error {
+	nonce := [3]uint32{0, 0, bits.ReverseBytes32(seqNum)}
+	s := chacha20.New(c.contentKey, nonce)
+	var polyKey [32]byte
+	s.XORKeyStream(polyKey[:], polyKey[:])
+	s.Advance() // skip next 32 bytes
+
+	// There is no blocksize, so fall back to multiple of 8 byte
+	// padding, as described in RFC 4253, Sec 6.
+	const packetSizeMultiple = 8
+
+	padding := packetSizeMultiple - (1+len(payload))%packetSizeMultiple
+	if padding < 4 {
+		padding += packetSizeMultiple
+	}
+
+	// size (4 bytes), padding (1), payload, padding, tag.
+	totalLength := 4 + 1 + len(payload) + padding + poly1305.TagSize
+	if cap(c.buf) < totalLength {
+		c.buf = make([]byte, totalLength)
+	} else {
+		c.buf = c.buf[:totalLength]
+	}
+
+	binary.BigEndian.PutUint32(c.buf, uint32(1+len(payload)+padding))
+	chacha20.New(c.lengthKey, nonce).XORKeyStream(c.buf, c.buf[:4])
+	c.buf[4] = byte(padding)
+	copy(c.buf[5:], payload)
+	packetEnd := 5 + len(payload) + padding
+	if _, err := io.ReadFull(rand, c.buf[5+len(payload):packetEnd]); err != nil {
+		return err
+	}
+
+	s.XORKeyStream(c.buf[4:], c.buf[4:packetEnd])
+
+	var mac [poly1305.TagSize]byte
+	poly1305.Sum(&mac, c.buf[:packetEnd], &polyKey)
+
+	copy(c.buf[packetEnd:], mac[:])
+
+	if _, err := w.Write(c.buf); err != nil {
+		return err
+	}
+	return nil
+}

+ 23 - 2
vendor/golang.org/x/crypto/ssh/client.go

@@ -9,6 +9,7 @@ import (
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
 	"net"
 	"net"
+	"os"
 	"sync"
 	"sync"
 	"time"
 	"time"
 )
 )
@@ -18,6 +19,8 @@ import (
 type Client struct {
 type Client struct {
 	Conn
 	Conn
 
 
+	handleForwardsOnce sync.Once // guards calling (*Client).handleForwards
+
 	forwards        forwardList // forwarded tcpip connections from the remote side
 	forwards        forwardList // forwarded tcpip connections from the remote side
 	mu              sync.Mutex
 	mu              sync.Mutex
 	channelHandlers map[string]chan NewChannel
 	channelHandlers map[string]chan NewChannel
@@ -59,8 +62,6 @@ func NewClient(c Conn, chans <-chan NewChannel, reqs <-chan *Request) *Client {
 		conn.Wait()
 		conn.Wait()
 		conn.forwards.closeAll()
 		conn.forwards.closeAll()
 	}()
 	}()
-	go conn.forwards.handleChannels(conn.HandleChannelOpen("forwarded-tcpip"))
-	go conn.forwards.handleChannels(conn.HandleChannelOpen("forwarded-streamlocal@openssh.com"))
 	return conn
 	return conn
 }
 }
 
 
@@ -187,6 +188,10 @@ func Dial(network, addr string, config *ClientConfig) (*Client, error) {
 // net.Conn underlying the the SSH connection.
 // net.Conn underlying the the SSH connection.
 type HostKeyCallback func(hostname string, remote net.Addr, key PublicKey) error
 type HostKeyCallback func(hostname string, remote net.Addr, key PublicKey) error
 
 
+// BannerCallback is the function type used for treat the banner sent by
+// the server. A BannerCallback receives the message sent by the remote server.
+type BannerCallback func(message string) error
+
 // A ClientConfig structure is used to configure a Client. It must not be
 // A ClientConfig structure is used to configure a Client. It must not be
 // modified after having been passed to an SSH function.
 // modified after having been passed to an SSH function.
 type ClientConfig struct {
 type ClientConfig struct {
@@ -209,6 +214,12 @@ type ClientConfig struct {
 	// FixedHostKey can be used for simplistic host key checks.
 	// FixedHostKey can be used for simplistic host key checks.
 	HostKeyCallback HostKeyCallback
 	HostKeyCallback HostKeyCallback
 
 
+	// BannerCallback is called during the SSH dance to display a custom
+	// server's message. The client configuration can supply this callback to
+	// handle it as wished. The function BannerDisplayStderr can be used for
+	// simplistic display on Stderr.
+	BannerCallback BannerCallback
+
 	// ClientVersion contains the version identification string that will
 	// ClientVersion contains the version identification string that will
 	// be used for the connection. If empty, a reasonable default is used.
 	// be used for the connection. If empty, a reasonable default is used.
 	ClientVersion string
 	ClientVersion string
@@ -255,3 +266,13 @@ func FixedHostKey(key PublicKey) HostKeyCallback {
 	hk := &fixedHostKey{key}
 	hk := &fixedHostKey{key}
 	return hk.check
 	return hk.check
 }
 }
+
+// BannerDisplayStderr returns a function that can be used for
+// ClientConfig.BannerCallback to display banners on os.Stderr.
+func BannerDisplayStderr() BannerCallback {
+	return func(banner string) error {
+		_, err := os.Stderr.WriteString(banner)
+
+		return err
+	}
+}

+ 80 - 41
vendor/golang.org/x/crypto/ssh/client_auth.go

@@ -11,6 +11,14 @@ import (
 	"io"
 	"io"
 )
 )
 
 
+type authResult int
+
+const (
+	authFailure authResult = iota
+	authPartialSuccess
+	authSuccess
+)
+
 // clientAuthenticate authenticates with the remote server. See RFC 4252.
 // clientAuthenticate authenticates with the remote server. See RFC 4252.
 func (c *connection) clientAuthenticate(config *ClientConfig) error {
 func (c *connection) clientAuthenticate(config *ClientConfig) error {
 	// initiate user auth session
 	// initiate user auth session
@@ -37,11 +45,12 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error {
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
-		if ok {
+		if ok == authSuccess {
 			// success
 			// success
 			return nil
 			return nil
+		} else if ok == authFailure {
+			tried[auth.method()] = true
 		}
 		}
-		tried[auth.method()] = true
 		if methods == nil {
 		if methods == nil {
 			methods = lastMethods
 			methods = lastMethods
 		}
 		}
@@ -82,7 +91,7 @@ type AuthMethod interface {
 	// If authentication is not successful, a []string of alternative
 	// If authentication is not successful, a []string of alternative
 	// method names is returned. If the slice is nil, it will be ignored
 	// method names is returned. If the slice is nil, it will be ignored
 	// and the previous set of possible methods will be reused.
 	// and the previous set of possible methods will be reused.
-	auth(session []byte, user string, p packetConn, rand io.Reader) (bool, []string, error)
+	auth(session []byte, user string, p packetConn, rand io.Reader) (authResult, []string, error)
 
 
 	// method returns the RFC 4252 method name.
 	// method returns the RFC 4252 method name.
 	method() string
 	method() string
@@ -91,13 +100,13 @@ type AuthMethod interface {
 // "none" authentication, RFC 4252 section 5.2.
 // "none" authentication, RFC 4252 section 5.2.
 type noneAuth int
 type noneAuth int
 
 
-func (n *noneAuth) auth(session []byte, user string, c packetConn, rand io.Reader) (bool, []string, error) {
+func (n *noneAuth) auth(session []byte, user string, c packetConn, rand io.Reader) (authResult, []string, error) {
 	if err := c.writePacket(Marshal(&userAuthRequestMsg{
 	if err := c.writePacket(Marshal(&userAuthRequestMsg{
 		User:    user,
 		User:    user,
 		Service: serviceSSH,
 		Service: serviceSSH,
 		Method:  "none",
 		Method:  "none",
 	})); err != nil {
 	})); err != nil {
-		return false, nil, err
+		return authFailure, nil, err
 	}
 	}
 
 
 	return handleAuthResponse(c)
 	return handleAuthResponse(c)
@@ -111,7 +120,7 @@ func (n *noneAuth) method() string {
 // a function call, e.g. by prompting the user.
 // a function call, e.g. by prompting the user.
 type passwordCallback func() (password string, err error)
 type passwordCallback func() (password string, err error)
 
 
-func (cb passwordCallback) auth(session []byte, user string, c packetConn, rand io.Reader) (bool, []string, error) {
+func (cb passwordCallback) auth(session []byte, user string, c packetConn, rand io.Reader) (authResult, []string, error) {
 	type passwordAuthMsg struct {
 	type passwordAuthMsg struct {
 		User     string `sshtype:"50"`
 		User     string `sshtype:"50"`
 		Service  string
 		Service  string
@@ -125,7 +134,7 @@ func (cb passwordCallback) auth(session []byte, user string, c packetConn, rand
 	// The program may only find out that the user doesn't have a password
 	// The program may only find out that the user doesn't have a password
 	// when prompting.
 	// when prompting.
 	if err != nil {
 	if err != nil {
-		return false, nil, err
+		return authFailure, nil, err
 	}
 	}
 
 
 	if err := c.writePacket(Marshal(&passwordAuthMsg{
 	if err := c.writePacket(Marshal(&passwordAuthMsg{
@@ -135,7 +144,7 @@ func (cb passwordCallback) auth(session []byte, user string, c packetConn, rand
 		Reply:    false,
 		Reply:    false,
 		Password: pw,
 		Password: pw,
 	})); err != nil {
 	})); err != nil {
-		return false, nil, err
+		return authFailure, nil, err
 	}
 	}
 
 
 	return handleAuthResponse(c)
 	return handleAuthResponse(c)
@@ -178,7 +187,7 @@ func (cb publicKeyCallback) method() string {
 	return "publickey"
 	return "publickey"
 }
 }
 
 
-func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand io.Reader) (bool, []string, error) {
+func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand io.Reader) (authResult, []string, error) {
 	// Authentication is performed by sending an enquiry to test if a key is
 	// Authentication is performed by sending an enquiry to test if a key is
 	// acceptable to the remote. If the key is acceptable, the client will
 	// acceptable to the remote. If the key is acceptable, the client will
 	// attempt to authenticate with the valid key.  If not the client will repeat
 	// attempt to authenticate with the valid key.  If not the client will repeat
@@ -186,13 +195,13 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
 
 
 	signers, err := cb()
 	signers, err := cb()
 	if err != nil {
 	if err != nil {
-		return false, nil, err
+		return authFailure, nil, err
 	}
 	}
 	var methods []string
 	var methods []string
 	for _, signer := range signers {
 	for _, signer := range signers {
 		ok, err := validateKey(signer.PublicKey(), user, c)
 		ok, err := validateKey(signer.PublicKey(), user, c)
 		if err != nil {
 		if err != nil {
-			return false, nil, err
+			return authFailure, nil, err
 		}
 		}
 		if !ok {
 		if !ok {
 			continue
 			continue
@@ -206,7 +215,7 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
 			Method:  cb.method(),
 			Method:  cb.method(),
 		}, []byte(pub.Type()), pubKey))
 		}, []byte(pub.Type()), pubKey))
 		if err != nil {
 		if err != nil {
-			return false, nil, err
+			return authFailure, nil, err
 		}
 		}
 
 
 		// manually wrap the serialized signature in a string
 		// manually wrap the serialized signature in a string
@@ -224,24 +233,24 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
 		}
 		}
 		p := Marshal(&msg)
 		p := Marshal(&msg)
 		if err := c.writePacket(p); err != nil {
 		if err := c.writePacket(p); err != nil {
-			return false, nil, err
+			return authFailure, nil, err
 		}
 		}
-		var success bool
+		var success authResult
 		success, methods, err = handleAuthResponse(c)
 		success, methods, err = handleAuthResponse(c)
 		if err != nil {
 		if err != nil {
-			return false, nil, err
+			return authFailure, nil, err
 		}
 		}
 
 
 		// If authentication succeeds or the list of available methods does not
 		// If authentication succeeds or the list of available methods does not
 		// contain the "publickey" method, do not attempt to authenticate with any
 		// contain the "publickey" method, do not attempt to authenticate with any
 		// other keys.  According to RFC 4252 Section 7, the latter can occur when
 		// other keys.  According to RFC 4252 Section 7, the latter can occur when
 		// additional authentication methods are required.
 		// additional authentication methods are required.
-		if success || !containsMethod(methods, cb.method()) {
+		if success == authSuccess || !containsMethod(methods, cb.method()) {
 			return success, methods, err
 			return success, methods, err
 		}
 		}
 	}
 	}
 
 
-	return false, methods, nil
+	return authFailure, methods, nil
 }
 }
 
 
 func containsMethod(methods []string, method string) bool {
 func containsMethod(methods []string, method string) bool {
@@ -283,7 +292,9 @@ func confirmKeyAck(key PublicKey, c packetConn) (bool, error) {
 		}
 		}
 		switch packet[0] {
 		switch packet[0] {
 		case msgUserAuthBanner:
 		case msgUserAuthBanner:
-			// TODO(gpaul): add callback to present the banner to the user
+			if err := handleBannerResponse(c, packet); err != nil {
+				return false, err
+			}
 		case msgUserAuthPubKeyOk:
 		case msgUserAuthPubKeyOk:
 			var msg userAuthPubKeyOkMsg
 			var msg userAuthPubKeyOkMsg
 			if err := Unmarshal(packet, &msg); err != nil {
 			if err := Unmarshal(packet, &msg); err != nil {
@@ -316,30 +327,53 @@ func PublicKeysCallback(getSigners func() (signers []Signer, err error)) AuthMet
 // handleAuthResponse returns whether the preceding authentication request succeeded
 // handleAuthResponse returns whether the preceding authentication request succeeded
 // along with a list of remaining authentication methods to try next and
 // along with a list of remaining authentication methods to try next and
 // an error if an unexpected response was received.
 // an error if an unexpected response was received.
-func handleAuthResponse(c packetConn) (bool, []string, error) {
+func handleAuthResponse(c packetConn) (authResult, []string, error) {
 	for {
 	for {
 		packet, err := c.readPacket()
 		packet, err := c.readPacket()
 		if err != nil {
 		if err != nil {
-			return false, nil, err
+			return authFailure, nil, err
 		}
 		}
 
 
 		switch packet[0] {
 		switch packet[0] {
 		case msgUserAuthBanner:
 		case msgUserAuthBanner:
-			// TODO: add callback to present the banner to the user
+			if err := handleBannerResponse(c, packet); err != nil {
+				return authFailure, nil, err
+			}
 		case msgUserAuthFailure:
 		case msgUserAuthFailure:
 			var msg userAuthFailureMsg
 			var msg userAuthFailureMsg
 			if err := Unmarshal(packet, &msg); err != nil {
 			if err := Unmarshal(packet, &msg); err != nil {
-				return false, nil, err
+				return authFailure, nil, err
+			}
+			if msg.PartialSuccess {
+				return authPartialSuccess, msg.Methods, nil
 			}
 			}
-			return false, msg.Methods, nil
+			return authFailure, msg.Methods, nil
 		case msgUserAuthSuccess:
 		case msgUserAuthSuccess:
-			return true, nil, nil
+			return authSuccess, nil, nil
 		default:
 		default:
-			return false, nil, unexpectedMessageError(msgUserAuthSuccess, packet[0])
+			return authFailure, nil, unexpectedMessageError(msgUserAuthSuccess, packet[0])
 		}
 		}
 	}
 	}
 }
 }
 
 
+func handleBannerResponse(c packetConn, packet []byte) error {
+	var msg userAuthBannerMsg
+	if err := Unmarshal(packet, &msg); err != nil {
+		return err
+	}
+
+	transport, ok := c.(*handshakeTransport)
+	if !ok {
+		return nil
+	}
+
+	if transport.bannerCallback != nil {
+		return transport.bannerCallback(msg.Message)
+	}
+
+	return nil
+}
+
 // KeyboardInteractiveChallenge should print questions, optionally
 // KeyboardInteractiveChallenge should print questions, optionally
 // disabling echoing (e.g. for passwords), and return all the answers.
 // disabling echoing (e.g. for passwords), and return all the answers.
 // Challenge may be called multiple times in a single session. After
 // Challenge may be called multiple times in a single session. After
@@ -359,7 +393,7 @@ func (cb KeyboardInteractiveChallenge) method() string {
 	return "keyboard-interactive"
 	return "keyboard-interactive"
 }
 }
 
 
-func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packetConn, rand io.Reader) (bool, []string, error) {
+func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packetConn, rand io.Reader) (authResult, []string, error) {
 	type initiateMsg struct {
 	type initiateMsg struct {
 		User       string `sshtype:"50"`
 		User       string `sshtype:"50"`
 		Service    string
 		Service    string
@@ -373,37 +407,42 @@ func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packe
 		Service: serviceSSH,
 		Service: serviceSSH,
 		Method:  "keyboard-interactive",
 		Method:  "keyboard-interactive",
 	})); err != nil {
 	})); err != nil {
-		return false, nil, err
+		return authFailure, nil, err
 	}
 	}
 
 
 	for {
 	for {
 		packet, err := c.readPacket()
 		packet, err := c.readPacket()
 		if err != nil {
 		if err != nil {
-			return false, nil, err
+			return authFailure, nil, err
 		}
 		}
 
 
 		// like handleAuthResponse, but with less options.
 		// like handleAuthResponse, but with less options.
 		switch packet[0] {
 		switch packet[0] {
 		case msgUserAuthBanner:
 		case msgUserAuthBanner:
-			// TODO: Print banners during userauth.
+			if err := handleBannerResponse(c, packet); err != nil {
+				return authFailure, nil, err
+			}
 			continue
 			continue
 		case msgUserAuthInfoRequest:
 		case msgUserAuthInfoRequest:
 			// OK
 			// OK
 		case msgUserAuthFailure:
 		case msgUserAuthFailure:
 			var msg userAuthFailureMsg
 			var msg userAuthFailureMsg
 			if err := Unmarshal(packet, &msg); err != nil {
 			if err := Unmarshal(packet, &msg); err != nil {
-				return false, nil, err
+				return authFailure, nil, err
+			}
+			if msg.PartialSuccess {
+				return authPartialSuccess, msg.Methods, nil
 			}
 			}
-			return false, msg.Methods, nil
+			return authFailure, msg.Methods, nil
 		case msgUserAuthSuccess:
 		case msgUserAuthSuccess:
-			return true, nil, nil
+			return authSuccess, nil, nil
 		default:
 		default:
-			return false, nil, unexpectedMessageError(msgUserAuthInfoRequest, packet[0])
+			return authFailure, nil, unexpectedMessageError(msgUserAuthInfoRequest, packet[0])
 		}
 		}
 
 
 		var msg userAuthInfoRequestMsg
 		var msg userAuthInfoRequestMsg
 		if err := Unmarshal(packet, &msg); err != nil {
 		if err := Unmarshal(packet, &msg); err != nil {
-			return false, nil, err
+			return authFailure, nil, err
 		}
 		}
 
 
 		// Manually unpack the prompt/echo pairs.
 		// Manually unpack the prompt/echo pairs.
@@ -413,7 +452,7 @@ func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packe
 		for i := 0; i < int(msg.NumPrompts); i++ {
 		for i := 0; i < int(msg.NumPrompts); i++ {
 			prompt, r, ok := parseString(rest)
 			prompt, r, ok := parseString(rest)
 			if !ok || len(r) == 0 {
 			if !ok || len(r) == 0 {
-				return false, nil, errors.New("ssh: prompt format error")
+				return authFailure, nil, errors.New("ssh: prompt format error")
 			}
 			}
 			prompts = append(prompts, string(prompt))
 			prompts = append(prompts, string(prompt))
 			echos = append(echos, r[0] != 0)
 			echos = append(echos, r[0] != 0)
@@ -421,16 +460,16 @@ func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packe
 		}
 		}
 
 
 		if len(rest) != 0 {
 		if len(rest) != 0 {
-			return false, nil, errors.New("ssh: extra data following keyboard-interactive pairs")
+			return authFailure, nil, errors.New("ssh: extra data following keyboard-interactive pairs")
 		}
 		}
 
 
 		answers, err := cb(msg.User, msg.Instruction, prompts, echos)
 		answers, err := cb(msg.User, msg.Instruction, prompts, echos)
 		if err != nil {
 		if err != nil {
-			return false, nil, err
+			return authFailure, nil, err
 		}
 		}
 
 
 		if len(answers) != len(prompts) {
 		if len(answers) != len(prompts) {
-			return false, nil, errors.New("ssh: not enough answers from keyboard-interactive callback")
+			return authFailure, nil, errors.New("ssh: not enough answers from keyboard-interactive callback")
 		}
 		}
 		responseLength := 1 + 4
 		responseLength := 1 + 4
 		for _, a := range answers {
 		for _, a := range answers {
@@ -446,7 +485,7 @@ func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packe
 		}
 		}
 
 
 		if err := c.writePacket(serialized); err != nil {
 		if err := c.writePacket(serialized); err != nil {
-			return false, nil, err
+			return authFailure, nil, err
 		}
 		}
 	}
 	}
 }
 }
@@ -456,10 +495,10 @@ type retryableAuthMethod struct {
 	maxTries   int
 	maxTries   int
 }
 }
 
 
-func (r *retryableAuthMethod) auth(session []byte, user string, c packetConn, rand io.Reader) (ok bool, methods []string, err error) {
+func (r *retryableAuthMethod) auth(session []byte, user string, c packetConn, rand io.Reader) (ok authResult, methods []string, err error) {
 	for i := 0; r.maxTries <= 0 || i < r.maxTries; i++ {
 	for i := 0; r.maxTries <= 0 || i < r.maxTries; i++ {
 		ok, methods, err = r.authMethod.auth(session, user, c, rand)
 		ok, methods, err = r.authMethod.auth(session, user, c, rand)
-		if ok || err != nil { // either success or error terminate
+		if ok != authFailure || err != nil { // either success, partial success or error terminate
 			return ok, methods, err
 			return ok, methods, err
 		}
 		}
 	}
 	}

+ 15 - 5
vendor/golang.org/x/crypto/ssh/common.go

@@ -24,11 +24,21 @@ const (
 	serviceSSH      = "ssh-connection"
 	serviceSSH      = "ssh-connection"
 )
 )
 
 
-// supportedCiphers specifies the supported ciphers in preference order.
+// supportedCiphers lists ciphers we support but might not recommend.
 var supportedCiphers = []string{
 var supportedCiphers = []string{
 	"aes128-ctr", "aes192-ctr", "aes256-ctr",
 	"aes128-ctr", "aes192-ctr", "aes256-ctr",
 	"aes128-gcm@openssh.com",
 	"aes128-gcm@openssh.com",
-	"arcfour256", "arcfour128",
+	chacha20Poly1305ID,
+	"arcfour256", "arcfour128", "arcfour",
+	aes128cbcID,
+	tripledescbcID,
+}
+
+// preferredCiphers specifies the default preference for ciphers.
+var preferredCiphers = []string{
+	"aes128-gcm@openssh.com",
+	chacha20Poly1305ID,
+	"aes128-ctr", "aes192-ctr", "aes256-ctr",
 }
 }
 
 
 // supportedKexAlgos specifies the supported key-exchange algorithms in
 // supportedKexAlgos specifies the supported key-exchange algorithms in
@@ -211,7 +221,7 @@ func (c *Config) SetDefaults() {
 		c.Rand = rand.Reader
 		c.Rand = rand.Reader
 	}
 	}
 	if c.Ciphers == nil {
 	if c.Ciphers == nil {
-		c.Ciphers = supportedCiphers
+		c.Ciphers = preferredCiphers
 	}
 	}
 	var ciphers []string
 	var ciphers []string
 	for _, c := range c.Ciphers {
 	for _, c := range c.Ciphers {
@@ -242,7 +252,7 @@ func (c *Config) SetDefaults() {
 
 
 // buildDataSignedForAuth returns the data that is signed in order to prove
 // buildDataSignedForAuth returns the data that is signed in order to prove
 // possession of a private key. See RFC 4252, section 7.
 // possession of a private key. See RFC 4252, section 7.
-func buildDataSignedForAuth(sessionId []byte, req userAuthRequestMsg, algo, pubKey []byte) []byte {
+func buildDataSignedForAuth(sessionID []byte, req userAuthRequestMsg, algo, pubKey []byte) []byte {
 	data := struct {
 	data := struct {
 		Session []byte
 		Session []byte
 		Type    byte
 		Type    byte
@@ -253,7 +263,7 @@ func buildDataSignedForAuth(sessionId []byte, req userAuthRequestMsg, algo, pubK
 		Algo    []byte
 		Algo    []byte
 		PubKey  []byte
 		PubKey  []byte
 	}{
 	}{
-		sessionId,
+		sessionID,
 		msgUserAuthRequest,
 		msgUserAuthRequest,
 		req.User,
 		req.User,
 		req.Service,
 		req.Service,

+ 6 - 0
vendor/golang.org/x/crypto/ssh/handshake.go

@@ -78,6 +78,11 @@ type handshakeTransport struct {
 	dialAddress     string
 	dialAddress     string
 	remoteAddr      net.Addr
 	remoteAddr      net.Addr
 
 
+	// bannerCallback is non-empty if we are the client and it has been set in
+	// ClientConfig. In that case it is called during the user authentication
+	// dance to handle a custom server's message.
+	bannerCallback BannerCallback
+
 	// Algorithms agreed in the last key exchange.
 	// Algorithms agreed in the last key exchange.
 	algorithms *algorithms
 	algorithms *algorithms
 
 
@@ -120,6 +125,7 @@ func newClientTransport(conn keyingTransport, clientVersion, serverVersion []byt
 	t.dialAddress = dialAddr
 	t.dialAddress = dialAddr
 	t.remoteAddr = addr
 	t.remoteAddr = addr
 	t.hostKeyCallback = config.HostKeyCallback
 	t.hostKeyCallback = config.HostKeyCallback
+	t.bannerCallback = config.BannerCallback
 	if config.HostKeyAlgorithms != nil {
 	if config.HostKeyAlgorithms != nil {
 		t.hostKeyAlgorithms = config.HostKeyAlgorithms
 		t.hostKeyAlgorithms = config.HostKeyAlgorithms
 	} else {
 	} else {

+ 12 - 12
vendor/golang.org/x/crypto/ssh/kex.go

@@ -119,7 +119,7 @@ func (group *dhGroup) Client(c packetConn, randSource io.Reader, magics *handsha
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	kInt, err := group.diffieHellman(kexDHReply.Y, x)
+	ki, err := group.diffieHellman(kexDHReply.Y, x)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -129,8 +129,8 @@ func (group *dhGroup) Client(c packetConn, randSource io.Reader, magics *handsha
 	writeString(h, kexDHReply.HostKey)
 	writeString(h, kexDHReply.HostKey)
 	writeInt(h, X)
 	writeInt(h, X)
 	writeInt(h, kexDHReply.Y)
 	writeInt(h, kexDHReply.Y)
-	K := make([]byte, intLength(kInt))
-	marshalInt(K, kInt)
+	K := make([]byte, intLength(ki))
+	marshalInt(K, ki)
 	h.Write(K)
 	h.Write(K)
 
 
 	return &kexResult{
 	return &kexResult{
@@ -164,7 +164,7 @@ func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handsha
 	}
 	}
 
 
 	Y := new(big.Int).Exp(group.g, y, group.p)
 	Y := new(big.Int).Exp(group.g, y, group.p)
-	kInt, err := group.diffieHellman(kexDHInit.X, y)
+	ki, err := group.diffieHellman(kexDHInit.X, y)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -177,8 +177,8 @@ func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handsha
 	writeInt(h, kexDHInit.X)
 	writeInt(h, kexDHInit.X)
 	writeInt(h, Y)
 	writeInt(h, Y)
 
 
-	K := make([]byte, intLength(kInt))
-	marshalInt(K, kInt)
+	K := make([]byte, intLength(ki))
+	marshalInt(K, ki)
 	h.Write(K)
 	h.Write(K)
 
 
 	H := h.Sum(nil)
 	H := h.Sum(nil)
@@ -462,9 +462,9 @@ func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handsh
 	writeString(h, kp.pub[:])
 	writeString(h, kp.pub[:])
 	writeString(h, reply.EphemeralPubKey)
 	writeString(h, reply.EphemeralPubKey)
 
 
-	kInt := new(big.Int).SetBytes(secret[:])
-	K := make([]byte, intLength(kInt))
-	marshalInt(K, kInt)
+	ki := new(big.Int).SetBytes(secret[:])
+	K := make([]byte, intLength(ki))
+	marshalInt(K, ki)
 	h.Write(K)
 	h.Write(K)
 
 
 	return &kexResult{
 	return &kexResult{
@@ -510,9 +510,9 @@ func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handsh
 	writeString(h, kexInit.ClientPubKey)
 	writeString(h, kexInit.ClientPubKey)
 	writeString(h, kp.pub[:])
 	writeString(h, kp.pub[:])
 
 
-	kInt := new(big.Int).SetBytes(secret[:])
-	K := make([]byte, intLength(kInt))
-	marshalInt(K, kInt)
+	ki := new(big.Int).SetBytes(secret[:])
+	K := make([]byte, intLength(ki))
+	marshalInt(K, ki)
 	h.Write(K)
 	h.Write(K)
 
 
 	H := h.Sum(nil)
 	H := h.Sum(nil)

+ 24 - 23
vendor/golang.org/x/crypto/ssh/keys.go

@@ -276,7 +276,8 @@ type PublicKey interface {
 	Type() string
 	Type() string
 
 
 	// Marshal returns the serialized key data in SSH wire format,
 	// Marshal returns the serialized key data in SSH wire format,
-	// with the name prefix.
+	// with the name prefix. To unmarshal the returned data, use
+	// the ParsePublicKey function.
 	Marshal() []byte
 	Marshal() []byte
 
 
 	// Verify that sig is a signature on the given data using this
 	// Verify that sig is a signature on the given data using this
@@ -363,7 +364,7 @@ func (r *rsaPublicKey) CryptoPublicKey() crypto.PublicKey {
 
 
 type dsaPublicKey dsa.PublicKey
 type dsaPublicKey dsa.PublicKey
 
 
-func (r *dsaPublicKey) Type() string {
+func (k *dsaPublicKey) Type() string {
 	return "ssh-dss"
 	return "ssh-dss"
 }
 }
 
 
@@ -481,12 +482,12 @@ func (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) {
 
 
 type ecdsaPublicKey ecdsa.PublicKey
 type ecdsaPublicKey ecdsa.PublicKey
 
 
-func (key *ecdsaPublicKey) Type() string {
-	return "ecdsa-sha2-" + key.nistID()
+func (k *ecdsaPublicKey) Type() string {
+	return "ecdsa-sha2-" + k.nistID()
 }
 }
 
 
-func (key *ecdsaPublicKey) nistID() string {
-	switch key.Params().BitSize {
+func (k *ecdsaPublicKey) nistID() string {
+	switch k.Params().BitSize {
 	case 256:
 	case 256:
 		return "nistp256"
 		return "nistp256"
 	case 384:
 	case 384:
@@ -499,7 +500,7 @@ func (key *ecdsaPublicKey) nistID() string {
 
 
 type ed25519PublicKey ed25519.PublicKey
 type ed25519PublicKey ed25519.PublicKey
 
 
-func (key ed25519PublicKey) Type() string {
+func (k ed25519PublicKey) Type() string {
 	return KeyAlgoED25519
 	return KeyAlgoED25519
 }
 }
 
 
@@ -518,23 +519,23 @@ func parseED25519(in []byte) (out PublicKey, rest []byte, err error) {
 	return (ed25519PublicKey)(key), w.Rest, nil
 	return (ed25519PublicKey)(key), w.Rest, nil
 }
 }
 
 
-func (key ed25519PublicKey) Marshal() []byte {
+func (k ed25519PublicKey) Marshal() []byte {
 	w := struct {
 	w := struct {
 		Name     string
 		Name     string
 		KeyBytes []byte
 		KeyBytes []byte
 	}{
 	}{
 		KeyAlgoED25519,
 		KeyAlgoED25519,
-		[]byte(key),
+		[]byte(k),
 	}
 	}
 	return Marshal(&w)
 	return Marshal(&w)
 }
 }
 
 
-func (key ed25519PublicKey) Verify(b []byte, sig *Signature) error {
-	if sig.Format != key.Type() {
-		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, key.Type())
+func (k ed25519PublicKey) Verify(b []byte, sig *Signature) error {
+	if sig.Format != k.Type() {
+		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
 	}
 	}
 
 
-	edKey := (ed25519.PublicKey)(key)
+	edKey := (ed25519.PublicKey)(k)
 	if ok := ed25519.Verify(edKey, b, sig.Blob); !ok {
 	if ok := ed25519.Verify(edKey, b, sig.Blob); !ok {
 		return errors.New("ssh: signature did not verify")
 		return errors.New("ssh: signature did not verify")
 	}
 	}
@@ -595,9 +596,9 @@ func parseECDSA(in []byte) (out PublicKey, rest []byte, err error) {
 	return (*ecdsaPublicKey)(key), w.Rest, nil
 	return (*ecdsaPublicKey)(key), w.Rest, nil
 }
 }
 
 
-func (key *ecdsaPublicKey) Marshal() []byte {
+func (k *ecdsaPublicKey) Marshal() []byte {
 	// See RFC 5656, section 3.1.
 	// See RFC 5656, section 3.1.
-	keyBytes := elliptic.Marshal(key.Curve, key.X, key.Y)
+	keyBytes := elliptic.Marshal(k.Curve, k.X, k.Y)
 	// ECDSA publickey struct layout should match the struct used by
 	// ECDSA publickey struct layout should match the struct used by
 	// parseECDSACert in the x/crypto/ssh/agent package.
 	// parseECDSACert in the x/crypto/ssh/agent package.
 	w := struct {
 	w := struct {
@@ -605,20 +606,20 @@ func (key *ecdsaPublicKey) Marshal() []byte {
 		ID   string
 		ID   string
 		Key  []byte
 		Key  []byte
 	}{
 	}{
-		key.Type(),
-		key.nistID(),
+		k.Type(),
+		k.nistID(),
 		keyBytes,
 		keyBytes,
 	}
 	}
 
 
 	return Marshal(&w)
 	return Marshal(&w)
 }
 }
 
 
-func (key *ecdsaPublicKey) Verify(data []byte, sig *Signature) error {
-	if sig.Format != key.Type() {
-		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, key.Type())
+func (k *ecdsaPublicKey) Verify(data []byte, sig *Signature) error {
+	if sig.Format != k.Type() {
+		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
 	}
 	}
 
 
-	h := ecHash(key.Curve).New()
+	h := ecHash(k.Curve).New()
 	h.Write(data)
 	h.Write(data)
 	digest := h.Sum(nil)
 	digest := h.Sum(nil)
 
 
@@ -635,7 +636,7 @@ func (key *ecdsaPublicKey) Verify(data []byte, sig *Signature) error {
 		return err
 		return err
 	}
 	}
 
 
-	if ecdsa.Verify((*ecdsa.PublicKey)(key), digest, ecSig.R, ecSig.S) {
+	if ecdsa.Verify((*ecdsa.PublicKey)(k), digest, ecSig.R, ecSig.S) {
 		return nil
 		return nil
 	}
 	}
 	return errors.New("ssh: signature did not verify")
 	return errors.New("ssh: signature did not verify")
@@ -758,7 +759,7 @@ func NewPublicKey(key interface{}) (PublicKey, error) {
 		return (*rsaPublicKey)(key), nil
 		return (*rsaPublicKey)(key), nil
 	case *ecdsa.PublicKey:
 	case *ecdsa.PublicKey:
 		if !supportedEllipticCurve(key.Curve) {
 		if !supportedEllipticCurve(key.Curve) {
-			return nil, errors.New("ssh: only P-256, P-384 and P-521 EC keys are supported.")
+			return nil, errors.New("ssh: only P-256, P-384 and P-521 EC keys are supported")
 		}
 		}
 		return (*ecdsaPublicKey)(key), nil
 		return (*ecdsaPublicKey)(key), nil
 	case *dsa.PublicKey:
 	case *dsa.PublicKey:

+ 23 - 15
vendor/golang.org/x/crypto/ssh/messages.go

@@ -23,10 +23,6 @@ const (
 	msgUnimplemented = 3
 	msgUnimplemented = 3
 	msgDebug         = 4
 	msgDebug         = 4
 	msgNewKeys       = 21
 	msgNewKeys       = 21
-
-	// Standard authentication messages
-	msgUserAuthSuccess = 52
-	msgUserAuthBanner  = 53
 )
 )
 
 
 // SSH messages:
 // SSH messages:
@@ -137,6 +133,18 @@ type userAuthFailureMsg struct {
 	PartialSuccess bool
 	PartialSuccess bool
 }
 }
 
 
+// See RFC 4252, section 5.1
+const msgUserAuthSuccess = 52
+
+// See RFC 4252, section 5.4
+const msgUserAuthBanner = 53
+
+type userAuthBannerMsg struct {
+	Message string `sshtype:"53"`
+	// unused, but required to allow message parsing
+	Language string
+}
+
 // See RFC 4256, section 3.2
 // See RFC 4256, section 3.2
 const msgUserAuthInfoRequest = 60
 const msgUserAuthInfoRequest = 60
 const msgUserAuthInfoResponse = 61
 const msgUserAuthInfoResponse = 61
@@ -154,7 +162,7 @@ const msgChannelOpen = 90
 
 
 type channelOpenMsg struct {
 type channelOpenMsg struct {
 	ChanType         string `sshtype:"90"`
 	ChanType         string `sshtype:"90"`
-	PeersId          uint32
+	PeersID          uint32
 	PeersWindow      uint32
 	PeersWindow      uint32
 	MaxPacketSize    uint32
 	MaxPacketSize    uint32
 	TypeSpecificData []byte `ssh:"rest"`
 	TypeSpecificData []byte `ssh:"rest"`
@@ -165,7 +173,7 @@ const msgChannelData = 94
 
 
 // Used for debug print outs of packets.
 // Used for debug print outs of packets.
 type channelDataMsg struct {
 type channelDataMsg struct {
-	PeersId uint32 `sshtype:"94"`
+	PeersID uint32 `sshtype:"94"`
 	Length  uint32
 	Length  uint32
 	Rest    []byte `ssh:"rest"`
 	Rest    []byte `ssh:"rest"`
 }
 }
@@ -174,8 +182,8 @@ type channelDataMsg struct {
 const msgChannelOpenConfirm = 91
 const msgChannelOpenConfirm = 91
 
 
 type channelOpenConfirmMsg struct {
 type channelOpenConfirmMsg struct {
-	PeersId          uint32 `sshtype:"91"`
-	MyId             uint32
+	PeersID          uint32 `sshtype:"91"`
+	MyID             uint32
 	MyWindow         uint32
 	MyWindow         uint32
 	MaxPacketSize    uint32
 	MaxPacketSize    uint32
 	TypeSpecificData []byte `ssh:"rest"`
 	TypeSpecificData []byte `ssh:"rest"`
@@ -185,7 +193,7 @@ type channelOpenConfirmMsg struct {
 const msgChannelOpenFailure = 92
 const msgChannelOpenFailure = 92
 
 
 type channelOpenFailureMsg struct {
 type channelOpenFailureMsg struct {
-	PeersId  uint32 `sshtype:"92"`
+	PeersID  uint32 `sshtype:"92"`
 	Reason   RejectionReason
 	Reason   RejectionReason
 	Message  string
 	Message  string
 	Language string
 	Language string
@@ -194,7 +202,7 @@ type channelOpenFailureMsg struct {
 const msgChannelRequest = 98
 const msgChannelRequest = 98
 
 
 type channelRequestMsg struct {
 type channelRequestMsg struct {
-	PeersId             uint32 `sshtype:"98"`
+	PeersID             uint32 `sshtype:"98"`
 	Request             string
 	Request             string
 	WantReply           bool
 	WantReply           bool
 	RequestSpecificData []byte `ssh:"rest"`
 	RequestSpecificData []byte `ssh:"rest"`
@@ -204,28 +212,28 @@ type channelRequestMsg struct {
 const msgChannelSuccess = 99
 const msgChannelSuccess = 99
 
 
 type channelRequestSuccessMsg struct {
 type channelRequestSuccessMsg struct {
-	PeersId uint32 `sshtype:"99"`
+	PeersID uint32 `sshtype:"99"`
 }
 }
 
 
 // See RFC 4254, section 5.4.
 // See RFC 4254, section 5.4.
 const msgChannelFailure = 100
 const msgChannelFailure = 100
 
 
 type channelRequestFailureMsg struct {
 type channelRequestFailureMsg struct {
-	PeersId uint32 `sshtype:"100"`
+	PeersID uint32 `sshtype:"100"`
 }
 }
 
 
 // See RFC 4254, section 5.3
 // See RFC 4254, section 5.3
 const msgChannelClose = 97
 const msgChannelClose = 97
 
 
 type channelCloseMsg struct {
 type channelCloseMsg struct {
-	PeersId uint32 `sshtype:"97"`
+	PeersID uint32 `sshtype:"97"`
 }
 }
 
 
 // See RFC 4254, section 5.3
 // See RFC 4254, section 5.3
 const msgChannelEOF = 96
 const msgChannelEOF = 96
 
 
 type channelEOFMsg struct {
 type channelEOFMsg struct {
-	PeersId uint32 `sshtype:"96"`
+	PeersID uint32 `sshtype:"96"`
 }
 }
 
 
 // See RFC 4254, section 4
 // See RFC 4254, section 4
@@ -255,7 +263,7 @@ type globalRequestFailureMsg struct {
 const msgChannelWindowAdjust = 93
 const msgChannelWindowAdjust = 93
 
 
 type windowAdjustMsg struct {
 type windowAdjustMsg struct {
-	PeersId         uint32 `sshtype:"93"`
+	PeersID         uint32 `sshtype:"93"`
 	AdditionalBytes uint32
 	AdditionalBytes uint32
 }
 }
 
 

+ 3 - 3
vendor/golang.org/x/crypto/ssh/mux.go

@@ -278,7 +278,7 @@ func (m *mux) handleChannelOpen(packet []byte) error {
 
 
 	if msg.MaxPacketSize < minPacketLength || msg.MaxPacketSize > 1<<31 {
 	if msg.MaxPacketSize < minPacketLength || msg.MaxPacketSize > 1<<31 {
 		failMsg := channelOpenFailureMsg{
 		failMsg := channelOpenFailureMsg{
-			PeersId:  msg.PeersId,
+			PeersID:  msg.PeersID,
 			Reason:   ConnectionFailed,
 			Reason:   ConnectionFailed,
 			Message:  "invalid request",
 			Message:  "invalid request",
 			Language: "en_US.UTF-8",
 			Language: "en_US.UTF-8",
@@ -287,7 +287,7 @@ func (m *mux) handleChannelOpen(packet []byte) error {
 	}
 	}
 
 
 	c := m.newChannel(msg.ChanType, channelInbound, msg.TypeSpecificData)
 	c := m.newChannel(msg.ChanType, channelInbound, msg.TypeSpecificData)
-	c.remoteId = msg.PeersId
+	c.remoteId = msg.PeersID
 	c.maxRemotePayload = msg.MaxPacketSize
 	c.maxRemotePayload = msg.MaxPacketSize
 	c.remoteWin.add(msg.PeersWindow)
 	c.remoteWin.add(msg.PeersWindow)
 	m.incomingChannels <- c
 	m.incomingChannels <- c
@@ -313,7 +313,7 @@ func (m *mux) openChannel(chanType string, extra []byte) (*channel, error) {
 		PeersWindow:      ch.myWindow,
 		PeersWindow:      ch.myWindow,
 		MaxPacketSize:    ch.maxIncomingPayload,
 		MaxPacketSize:    ch.maxIncomingPayload,
 		TypeSpecificData: extra,
 		TypeSpecificData: extra,
-		PeersId:          ch.localId,
+		PeersID:          ch.localId,
 	}
 	}
 	if err := m.sendMessage(open); err != nil {
 	if err := m.sendMessage(open); err != nil {
 		return nil, err
 		return nil, err

+ 36 - 6
vendor/golang.org/x/crypto/ssh/server.go

@@ -95,6 +95,10 @@ type ServerConfig struct {
 	// Note that RFC 4253 section 4.2 requires that this string start with
 	// Note that RFC 4253 section 4.2 requires that this string start with
 	// "SSH-2.0-".
 	// "SSH-2.0-".
 	ServerVersion string
 	ServerVersion string
+
+	// BannerCallback, if present, is called and the return string is sent to
+	// the client after key exchange completed but before authentication.
+	BannerCallback func(conn ConnMetadata) string
 }
 }
 
 
 // AddHostKey adds a private key as a host key. If an existing host
 // AddHostKey adds a private key as a host key. If an existing host
@@ -162,6 +166,9 @@ type ServerConn struct {
 // unsuccessful, it closes the connection and returns an error.  The
 // unsuccessful, it closes the connection and returns an error.  The
 // Request and NewChannel channels must be serviced, or the connection
 // Request and NewChannel channels must be serviced, or the connection
 // will hang.
 // will hang.
+//
+// The returned error may be of type *ServerAuthError for
+// authentication errors.
 func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewChannel, <-chan *Request, error) {
 func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewChannel, <-chan *Request, error) {
 	fullConf := *config
 	fullConf := *config
 	fullConf.SetDefaults()
 	fullConf.SetDefaults()
@@ -252,7 +259,7 @@ func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error)
 func isAcceptableAlgo(algo string) bool {
 func isAcceptableAlgo(algo string) bool {
 	switch algo {
 	switch algo {
 	case KeyAlgoRSA, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, KeyAlgoED25519,
 	case KeyAlgoRSA, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, KeyAlgoED25519,
-		CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01:
+		CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01:
 		return true
 		return true
 	}
 	}
 	return false
 	return false
@@ -288,12 +295,13 @@ func checkSourceAddress(addr net.Addr, sourceAddrs string) error {
 	return fmt.Errorf("ssh: remote address %v is not allowed because of source-address restriction", addr)
 	return fmt.Errorf("ssh: remote address %v is not allowed because of source-address restriction", addr)
 }
 }
 
 
-// ServerAuthError implements the error interface. It appends any authentication
-// errors that may occur, and is returned if all of the authentication methods
-// provided by the user failed to authenticate.
+// ServerAuthError represents server authentication errors and is
+// sometimes returned by NewServerConn. It appends any authentication
+// errors that may occur, and is returned if all of the authentication
+// methods provided by the user failed to authenticate.
 type ServerAuthError struct {
 type ServerAuthError struct {
 	// Errors contains authentication errors returned by the authentication
 	// Errors contains authentication errors returned by the authentication
-	// callback methods.
+	// callback methods. The first entry is typically ErrNoAuth.
 	Errors []error
 	Errors []error
 }
 }
 
 
@@ -305,6 +313,13 @@ func (l ServerAuthError) Error() string {
 	return "[" + strings.Join(errs, ", ") + "]"
 	return "[" + strings.Join(errs, ", ") + "]"
 }
 }
 
 
+// ErrNoAuth is the error value returned if no
+// authentication method has been passed yet. This happens as a normal
+// part of the authentication loop, since the client first tries
+// 'none' authentication to discover available methods.
+// It is returned in ServerAuthError.Errors from NewServerConn.
+var ErrNoAuth = errors.New("ssh: no auth passed yet")
+
 func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, error) {
 func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, error) {
 	sessionID := s.transport.getSessionID()
 	sessionID := s.transport.getSessionID()
 	var cache pubKeyCache
 	var cache pubKeyCache
@@ -312,6 +327,7 @@ func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, err
 
 
 	authFailures := 0
 	authFailures := 0
 	var authErrs []error
 	var authErrs []error
+	var displayedBanner bool
 
 
 userAuthLoop:
 userAuthLoop:
 	for {
 	for {
@@ -343,8 +359,22 @@ userAuthLoop:
 		}
 		}
 
 
 		s.user = userAuthReq.User
 		s.user = userAuthReq.User
+
+		if !displayedBanner && config.BannerCallback != nil {
+			displayedBanner = true
+			msg := config.BannerCallback(s)
+			if msg != "" {
+				bannerMsg := &userAuthBannerMsg{
+					Message: msg,
+				}
+				if err := s.transport.writePacket(Marshal(bannerMsg)); err != nil {
+					return nil, err
+				}
+			}
+		}
+
 		perms = nil
 		perms = nil
-		authErr := errors.New("no auth passed yet")
+		authErr := ErrNoAuth
 
 
 		switch userAuthReq.Method {
 		switch userAuthReq.Method {
 		case "none":
 		case "none":

+ 1 - 1
vendor/golang.org/x/crypto/ssh/session.go

@@ -406,7 +406,7 @@ func (s *Session) Wait() error {
 		s.stdinPipeWriter.Close()
 		s.stdinPipeWriter.Close()
 	}
 	}
 	var copyError error
 	var copyError error
-	for _ = range s.copyFuncs {
+	for range s.copyFuncs {
 		if err := <-s.errors; err != nil && copyError == nil {
 		if err := <-s.errors; err != nil && copyError == nil {
 			copyError = err
 			copyError = err
 		}
 		}

+ 1 - 0
vendor/golang.org/x/crypto/ssh/streamlocal.go

@@ -32,6 +32,7 @@ type streamLocalChannelForwardMsg struct {
 
 
 // ListenUnix is similar to ListenTCP but uses a Unix domain socket.
 // ListenUnix is similar to ListenTCP but uses a Unix domain socket.
 func (c *Client) ListenUnix(socketPath string) (net.Listener, error) {
 func (c *Client) ListenUnix(socketPath string) (net.Listener, error) {
+	c.handleForwardsOnce.Do(c.handleForwards)
 	m := streamLocalChannelForwardMsg{
 	m := streamLocalChannelForwardMsg{
 		socketPath,
 		socketPath,
 	}
 	}

+ 9 - 0
vendor/golang.org/x/crypto/ssh/tcpip.go

@@ -90,10 +90,19 @@ type channelForwardMsg struct {
 	rport uint32
 	rport uint32
 }
 }
 
 
+// handleForwards starts goroutines handling forwarded connections.
+// It's called on first use by (*Client).ListenTCP to not launch
+// goroutines until needed.
+func (c *Client) handleForwards() {
+	go c.forwards.handleChannels(c.HandleChannelOpen("forwarded-tcpip"))
+	go c.forwards.handleChannels(c.HandleChannelOpen("forwarded-streamlocal@openssh.com"))
+}
+
 // ListenTCP requests the remote peer open a listening socket
 // ListenTCP requests the remote peer open a listening socket
 // on laddr. Incoming connections will be available by calling
 // on laddr. Incoming connections will be available by calling
 // Accept on the returned net.Listener.
 // Accept on the returned net.Listener.
 func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) {
 func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) {
+	c.handleForwardsOnce.Do(c.handleForwards)
 	if laddr.Port == 0 && isBrokenOpenSSHVersion(string(c.ServerVersion())) {
 	if laddr.Port == 0 && isBrokenOpenSSHVersion(string(c.ServerVersion())) {
 		return c.autoPortListenWorkaround(laddr)
 		return c.autoPortListenWorkaround(laddr)
 	}
 	}

+ 1 - 1
vendor/golang.org/x/crypto/ssh/terminal/terminal.go

@@ -617,7 +617,7 @@ func writeWithCRLF(w io.Writer, buf []byte) (n int, err error) {
 			if _, err = w.Write(crlf); err != nil {
 			if _, err = w.Write(crlf); err != nil {
 				return n, err
 				return n, err
 			}
 			}
-			n += 1
+			n++
 			buf = buf[1:]
 			buf = buf[1:]
 		}
 		}
 	}
 	}

+ 31 - 40
vendor/golang.org/x/crypto/ssh/terminal/util.go

@@ -17,44 +17,41 @@
 package terminal // import "golang.org/x/crypto/ssh/terminal"
 package terminal // import "golang.org/x/crypto/ssh/terminal"
 
 
 import (
 import (
-	"syscall"
-	"unsafe"
-
 	"golang.org/x/sys/unix"
 	"golang.org/x/sys/unix"
 )
 )
 
 
 // State contains the state of a terminal.
 // State contains the state of a terminal.
 type State struct {
 type State struct {
-	termios syscall.Termios
+	termios unix.Termios
 }
 }
 
 
 // IsTerminal returns true if the given file descriptor is a terminal.
 // IsTerminal returns true if the given file descriptor is a terminal.
 func IsTerminal(fd int) bool {
 func IsTerminal(fd int) bool {
-	var termios syscall.Termios
-	_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
-	return err == 0
+	_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
+	return err == nil
 }
 }
 
 
 // MakeRaw put the terminal connected to the given file descriptor into raw
 // MakeRaw put the terminal connected to the given file descriptor into raw
 // mode and returns the previous state of the terminal so that it can be
 // mode and returns the previous state of the terminal so that it can be
 // restored.
 // restored.
 func MakeRaw(fd int) (*State, error) {
 func MakeRaw(fd int) (*State, error) {
-	var oldState State
-	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
+	termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
+	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	newState := oldState.termios
+	oldState := State{termios: *termios}
+
 	// This attempts to replicate the behaviour documented for cfmakeraw in
 	// This attempts to replicate the behaviour documented for cfmakeraw in
 	// the termios(3) manpage.
 	// the termios(3) manpage.
-	newState.Iflag &^= syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON
-	newState.Oflag &^= syscall.OPOST
-	newState.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN
-	newState.Cflag &^= syscall.CSIZE | syscall.PARENB
-	newState.Cflag |= syscall.CS8
-	newState.Cc[unix.VMIN] = 1
-	newState.Cc[unix.VTIME] = 0
-	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
+	termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON
+	termios.Oflag &^= unix.OPOST
+	termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN
+	termios.Cflag &^= unix.CSIZE | unix.PARENB
+	termios.Cflag |= unix.CS8
+	termios.Cc[unix.VMIN] = 1
+	termios.Cc[unix.VTIME] = 0
+	if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, termios); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
@@ -64,60 +61,54 @@ func MakeRaw(fd int) (*State, error) {
 // GetState returns the current state of a terminal which may be useful to
 // GetState returns the current state of a terminal which may be useful to
 // restore the terminal after a signal.
 // restore the terminal after a signal.
 func GetState(fd int) (*State, error) {
 func GetState(fd int) (*State, error) {
-	var oldState State
-	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
+	termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
+	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	return &oldState, nil
+	return &State{termios: *termios}, nil
 }
 }
 
 
 // Restore restores the terminal connected to the given file descriptor to a
 // Restore restores the terminal connected to the given file descriptor to a
 // previous state.
 // previous state.
 func Restore(fd int, state *State) error {
 func Restore(fd int, state *State) error {
-	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0); err != 0 {
-		return err
-	}
-	return nil
+	return unix.IoctlSetTermios(fd, ioctlWriteTermios, &state.termios)
 }
 }
 
 
 // GetSize returns the dimensions of the given terminal.
 // GetSize returns the dimensions of the given terminal.
 func GetSize(fd int) (width, height int, err error) {
 func GetSize(fd int) (width, height int, err error) {
-	var dimensions [4]uint16
-
-	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 {
+	ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
+	if err != nil {
 		return -1, -1, err
 		return -1, -1, err
 	}
 	}
-	return int(dimensions[1]), int(dimensions[0]), nil
+	return int(ws.Col), int(ws.Row), nil
 }
 }
 
 
 // passwordReader is an io.Reader that reads from a specific file descriptor.
 // passwordReader is an io.Reader that reads from a specific file descriptor.
 type passwordReader int
 type passwordReader int
 
 
 func (r passwordReader) Read(buf []byte) (int, error) {
 func (r passwordReader) Read(buf []byte) (int, error) {
-	return syscall.Read(int(r), buf)
+	return unix.Read(int(r), buf)
 }
 }
 
 
 // ReadPassword reads a line of input from a terminal without local echo.  This
 // ReadPassword reads a line of input from a terminal without local echo.  This
 // is commonly used for inputting passwords and other sensitive data. The slice
 // is commonly used for inputting passwords and other sensitive data. The slice
 // returned does not include the \n.
 // returned does not include the \n.
 func ReadPassword(fd int) ([]byte, error) {
 func ReadPassword(fd int) ([]byte, error) {
-	var oldState syscall.Termios
-	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); err != 0 {
+	termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
+	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	newState := oldState
-	newState.Lflag &^= syscall.ECHO
-	newState.Lflag |= syscall.ICANON | syscall.ISIG
-	newState.Iflag |= syscall.ICRNL
-	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
+	newState := *termios
+	newState.Lflag &^= unix.ECHO
+	newState.Lflag |= unix.ICANON | unix.ISIG
+	newState.Iflag |= unix.ICRNL
+	if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &newState); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	defer func() {
-		syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0)
-	}()
+	defer unix.IoctlSetTermios(fd, ioctlWriteTermios, termios)
 
 
 	return readPasswordLine(passwordReader(fd))
 	return readPasswordLine(passwordReader(fd))
 }
 }

+ 18 - 22
vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go

@@ -14,7 +14,7 @@ import (
 
 
 // State contains the state of a terminal.
 // State contains the state of a terminal.
 type State struct {
 type State struct {
-	state *unix.Termios
+	termios unix.Termios
 }
 }
 
 
 // IsTerminal returns true if the given file descriptor is a terminal.
 // IsTerminal returns true if the given file descriptor is a terminal.
@@ -75,47 +75,43 @@ func ReadPassword(fd int) ([]byte, error) {
 // restored.
 // restored.
 // see http://cr.illumos.org/~webrev/andy_js/1060/
 // see http://cr.illumos.org/~webrev/andy_js/1060/
 func MakeRaw(fd int) (*State, error) {
 func MakeRaw(fd int) (*State, error) {
-	oldTermiosPtr, err := unix.IoctlGetTermios(fd, unix.TCGETS)
+	termios, err := unix.IoctlGetTermios(fd, unix.TCGETS)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	oldTermios := *oldTermiosPtr
-
-	newTermios := oldTermios
-	newTermios.Iflag &^= syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON
-	newTermios.Oflag &^= syscall.OPOST
-	newTermios.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN
-	newTermios.Cflag &^= syscall.CSIZE | syscall.PARENB
-	newTermios.Cflag |= syscall.CS8
-	newTermios.Cc[unix.VMIN] = 1
-	newTermios.Cc[unix.VTIME] = 0
-
-	if err := unix.IoctlSetTermios(fd, unix.TCSETS, &newTermios); err != nil {
+
+	oldState := State{termios: *termios}
+
+	termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON
+	termios.Oflag &^= unix.OPOST
+	termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN
+	termios.Cflag &^= unix.CSIZE | unix.PARENB
+	termios.Cflag |= unix.CS8
+	termios.Cc[unix.VMIN] = 1
+	termios.Cc[unix.VTIME] = 0
+
+	if err := unix.IoctlSetTermios(fd, unix.TCSETS, termios); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	return &State{
-		state: oldTermiosPtr,
-	}, nil
+	return &oldState, nil
 }
 }
 
 
 // Restore restores the terminal connected to the given file descriptor to a
 // Restore restores the terminal connected to the given file descriptor to a
 // previous state.
 // previous state.
 func Restore(fd int, oldState *State) error {
 func Restore(fd int, oldState *State) error {
-	return unix.IoctlSetTermios(fd, unix.TCSETS, oldState.state)
+	return unix.IoctlSetTermios(fd, unix.TCSETS, &oldState.termios)
 }
 }
 
 
 // GetState returns the current state of a terminal which may be useful to
 // GetState returns the current state of a terminal which may be useful to
 // restore the terminal after a signal.
 // restore the terminal after a signal.
 func GetState(fd int) (*State, error) {
 func GetState(fd int) (*State, error) {
-	oldTermiosPtr, err := unix.IoctlGetTermios(fd, unix.TCGETS)
+	termios, err := unix.IoctlGetTermios(fd, unix.TCGETS)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	return &State{
-		state: oldTermiosPtr,
-	}, nil
+	return &State{termios: *termios}, nil
 }
 }
 
 
 // GetSize returns the dimensions of the given terminal.
 // GetSize returns the dimensions of the given terminal.

+ 12 - 11
vendor/golang.org/x/crypto/ssh/terminal/util_windows.go

@@ -17,6 +17,8 @@
 package terminal
 package terminal
 
 
 import (
 import (
+	"os"
+
 	"golang.org/x/sys/windows"
 	"golang.org/x/sys/windows"
 )
 )
 
 
@@ -71,13 +73,6 @@ func GetSize(fd int) (width, height int, err error) {
 	return int(info.Size.X), int(info.Size.Y), nil
 	return int(info.Size.X), int(info.Size.Y), nil
 }
 }
 
 
-// passwordReader is an io.Reader that reads from a specific Windows HANDLE.
-type passwordReader int
-
-func (r passwordReader) Read(buf []byte) (int, error) {
-	return windows.Read(windows.Handle(r), buf)
-}
-
 // ReadPassword reads a line of input from a terminal without local echo.  This
 // ReadPassword reads a line of input from a terminal without local echo.  This
 // is commonly used for inputting passwords and other sensitive data. The slice
 // is commonly used for inputting passwords and other sensitive data. The slice
 // returned does not include the \n.
 // returned does not include the \n.
@@ -94,9 +89,15 @@ func ReadPassword(fd int) ([]byte, error) {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	defer func() {
-		windows.SetConsoleMode(windows.Handle(fd), old)
-	}()
+	defer windows.SetConsoleMode(windows.Handle(fd), old)
+
+	var h windows.Handle
+	p, _ := windows.GetCurrentProcess()
+	if err := windows.DuplicateHandle(p, windows.Handle(fd), p, &h, 0, false, windows.DUPLICATE_SAME_ACCESS); err != nil {
+		return nil, err
+	}
 
 
-	return readPasswordLine(passwordReader(fd))
+	f := os.NewFile(uintptr(h), "stdin")
+	defer f.Close()
+	return readPasswordLine(f)
 }
 }

+ 24 - 46
vendor/golang.org/x/crypto/ssh/transport.go

@@ -6,6 +6,7 @@ package ssh
 
 
 import (
 import (
 	"bufio"
 	"bufio"
+	"bytes"
 	"errors"
 	"errors"
 	"io"
 	"io"
 	"log"
 	"log"
@@ -76,17 +77,17 @@ type connectionState struct {
 // both directions are triggered by reading and writing a msgNewKey packet
 // both directions are triggered by reading and writing a msgNewKey packet
 // respectively.
 // respectively.
 func (t *transport) prepareKeyChange(algs *algorithms, kexResult *kexResult) error {
 func (t *transport) prepareKeyChange(algs *algorithms, kexResult *kexResult) error {
-	if ciph, err := newPacketCipher(t.reader.dir, algs.r, kexResult); err != nil {
+	ciph, err := newPacketCipher(t.reader.dir, algs.r, kexResult)
+	if err != nil {
 		return err
 		return err
-	} else {
-		t.reader.pendingKeyChange <- ciph
 	}
 	}
+	t.reader.pendingKeyChange <- ciph
 
 
-	if ciph, err := newPacketCipher(t.writer.dir, algs.w, kexResult); err != nil {
+	ciph, err = newPacketCipher(t.writer.dir, algs.w, kexResult)
+	if err != nil {
 		return err
 		return err
-	} else {
-		t.writer.pendingKeyChange <- ciph
 	}
 	}
+	t.writer.pendingKeyChange <- ciph
 
 
 	return nil
 	return nil
 }
 }
@@ -139,7 +140,7 @@ func (s *connectionState) readPacket(r *bufio.Reader) ([]byte, error) {
 			case cipher := <-s.pendingKeyChange:
 			case cipher := <-s.pendingKeyChange:
 				s.packetCipher = cipher
 				s.packetCipher = cipher
 			default:
 			default:
-				return nil, errors.New("ssh: got bogus newkeys message.")
+				return nil, errors.New("ssh: got bogus newkeys message")
 			}
 			}
 
 
 		case msgDisconnect:
 		case msgDisconnect:
@@ -232,52 +233,22 @@ var (
 	clientKeys = direction{[]byte{'A'}, []byte{'C'}, []byte{'E'}}
 	clientKeys = direction{[]byte{'A'}, []byte{'C'}, []byte{'E'}}
 )
 )
 
 
-// generateKeys generates key material for IV, MAC and encryption.
-func generateKeys(d direction, algs directionAlgorithms, kex *kexResult) (iv, key, macKey []byte) {
+// setupKeys sets the cipher and MAC keys from kex.K, kex.H and sessionId, as
+// described in RFC 4253, section 6.4. direction should either be serverKeys
+// (to setup server->client keys) or clientKeys (for client->server keys).
+func newPacketCipher(d direction, algs directionAlgorithms, kex *kexResult) (packetCipher, error) {
 	cipherMode := cipherModes[algs.Cipher]
 	cipherMode := cipherModes[algs.Cipher]
 	macMode := macModes[algs.MAC]
 	macMode := macModes[algs.MAC]
 
 
-	iv = make([]byte, cipherMode.ivSize)
-	key = make([]byte, cipherMode.keySize)
-	macKey = make([]byte, macMode.keySize)
+	iv := make([]byte, cipherMode.ivSize)
+	key := make([]byte, cipherMode.keySize)
+	macKey := make([]byte, macMode.keySize)
 
 
 	generateKeyMaterial(iv, d.ivTag, kex)
 	generateKeyMaterial(iv, d.ivTag, kex)
 	generateKeyMaterial(key, d.keyTag, kex)
 	generateKeyMaterial(key, d.keyTag, kex)
 	generateKeyMaterial(macKey, d.macKeyTag, kex)
 	generateKeyMaterial(macKey, d.macKeyTag, kex)
-	return
-}
-
-// setupKeys sets the cipher and MAC keys from kex.K, kex.H and sessionId, as
-// described in RFC 4253, section 6.4. direction should either be serverKeys
-// (to setup server->client keys) or clientKeys (for client->server keys).
-func newPacketCipher(d direction, algs directionAlgorithms, kex *kexResult) (packetCipher, error) {
-	iv, key, macKey := generateKeys(d, algs, kex)
-
-	if algs.Cipher == gcmCipherID {
-		return newGCMCipher(iv, key, macKey)
-	}
-
-	if algs.Cipher == aes128cbcID {
-		return newAESCBCCipher(iv, key, macKey, algs)
-	}
-
-	if algs.Cipher == tripledescbcID {
-		return newTripleDESCBCCipher(iv, key, macKey, algs)
-	}
 
 
-	c := &streamPacketCipher{
-		mac: macModes[algs.MAC].new(macKey),
-		etm: macModes[algs.MAC].etm,
-	}
-	c.macResult = make([]byte, c.mac.Size())
-
-	var err error
-	c.cipher, err = cipherModes[algs.Cipher].createStream(key, iv)
-	if err != nil {
-		return nil, err
-	}
-
-	return c, nil
+	return cipherModes[algs.Cipher].create(key, iv, macKey, algs)
 }
 }
 
 
 // generateKeyMaterial fills out with key material generated from tag, K, H
 // generateKeyMaterial fills out with key material generated from tag, K, H
@@ -342,7 +313,7 @@ func readVersion(r io.Reader) ([]byte, error) {
 	var ok bool
 	var ok bool
 	var buf [1]byte
 	var buf [1]byte
 
 
-	for len(versionString) < maxVersionStringBytes {
+	for length := 0; length < maxVersionStringBytes; length++ {
 		_, err := io.ReadFull(r, buf[:])
 		_, err := io.ReadFull(r, buf[:])
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
@@ -350,6 +321,13 @@ func readVersion(r io.Reader) ([]byte, error) {
 		// The RFC says that the version should be terminated with \r\n
 		// The RFC says that the version should be terminated with \r\n
 		// but several SSH servers actually only send a \n.
 		// but several SSH servers actually only send a \n.
 		if buf[0] == '\n' {
 		if buf[0] == '\n' {
+			if !bytes.HasPrefix(versionString, []byte("SSH-")) {
+				// RFC 4253 says we need to ignore all version string lines
+				// except the one containing the SSH version (provided that
+				// all the lines do not exceed 255 bytes in total).
+				versionString = versionString[:0]
+				continue
+			}
 			ok = true
 			ok = true
 			break
 			break
 		}
 		}

+ 2 - 0
vendor/golang.org/x/net/context/context.go

@@ -5,6 +5,8 @@
 // Package context defines the Context type, which carries deadlines,
 // Package context defines the Context type, which carries deadlines,
 // cancelation signals, and other request-scoped values across API boundaries
 // cancelation signals, and other request-scoped values across API boundaries
 // and between processes.
 // and between processes.
+// As of Go 1.7 this package is available in the standard library under the
+// name context.  https://golang.org/pkg/context.
 //
 //
 // Incoming requests to a server should create a Context, and outgoing calls to
 // Incoming requests to a server should create a Context, and outgoing calls to
 // servers should accept a Context. The chain of function calls between must
 // servers should accept a Context. The chain of function calls between must

+ 50 - 0
vendor/golang.org/x/net/http/httpguts/guts.go

@@ -0,0 +1,50 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package httpguts provides functions implementing various details
+// of the HTTP specification.
+//
+// This package is shared by the standard library (which vendors it)
+// and x/net/http2. It comes with no API stability promise.
+package httpguts
+
+import (
+	"net/textproto"
+	"strings"
+)
+
+// ValidTrailerHeader reports whether name is a valid header field name to appear
+// in trailers.
+// See RFC 7230, Section 4.1.2
+func ValidTrailerHeader(name string) bool {
+	name = textproto.CanonicalMIMEHeaderKey(name)
+	if strings.HasPrefix(name, "If-") || badTrailer[name] {
+		return false
+	}
+	return true
+}
+
+var badTrailer = map[string]bool{
+	"Authorization":       true,
+	"Cache-Control":       true,
+	"Connection":          true,
+	"Content-Encoding":    true,
+	"Content-Length":      true,
+	"Content-Range":       true,
+	"Content-Type":        true,
+	"Expect":              true,
+	"Host":                true,
+	"Keep-Alive":          true,
+	"Max-Forwards":        true,
+	"Pragma":              true,
+	"Proxy-Authenticate":  true,
+	"Proxy-Authorization": true,
+	"Proxy-Connection":    true,
+	"Range":               true,
+	"Realm":               true,
+	"Te":                  true,
+	"Trailer":             true,
+	"Transfer-Encoding":   true,
+	"Www-Authenticate":    true,
+}

+ 1 - 6
vendor/golang.org/x/net/lex/httplex/httplex.go → vendor/golang.org/x/net/http/httpguts/httplex.go

@@ -2,12 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-// Package httplex contains rules around lexical matters of various
-// HTTP-related specifications.
-//
-// This package is shared by the standard library (which vendors it)
-// and x/net/http2. It comes with no API stability promise.
-package httplex
+package httpguts
 
 
 import (
 import (
 	"net"
 	"net"

+ 1 - 1
vendor/golang.org/x/net/http2/ciphers.go

@@ -5,7 +5,7 @@
 package http2
 package http2
 
 
 // A list of the possible cipher suite ids. Taken from
 // A list of the possible cipher suite ids. Taken from
-// http://www.iana.org/assignments/tls-parameters/tls-parameters.txt
+// https://www.iana.org/assignments/tls-parameters/tls-parameters.txt
 
 
 const (
 const (
 	cipher_TLS_NULL_WITH_NULL_NULL               uint16 = 0x0000
 	cipher_TLS_NULL_WITH_NULL_NULL               uint16 = 0x0000

+ 1 - 1
vendor/golang.org/x/net/http2/configure_transport.go

@@ -73,7 +73,7 @@ type noDialH2RoundTripper struct{ t *Transport }
 
 
 func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
 func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
 	res, err := rt.t.RoundTrip(req)
 	res, err := rt.t.RoundTrip(req)
-	if err == ErrNoCachedConn {
+	if isNoCachedConnError(err) {
 		return nil, http.ErrSkipAltProtocol
 		return nil, http.ErrSkipAltProtocol
 	}
 	}
 	return res, err
 	return res, err

+ 2 - 2
vendor/golang.org/x/net/http2/frame.go

@@ -14,8 +14,8 @@ import (
 	"strings"
 	"strings"
 	"sync"
 	"sync"
 
 
+	"golang.org/x/net/http/httpguts"
 	"golang.org/x/net/http2/hpack"
 	"golang.org/x/net/http2/hpack"
-	"golang.org/x/net/lex/httplex"
 )
 )
 
 
 const frameHeaderLen = 9
 const frameHeaderLen = 9
@@ -1462,7 +1462,7 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
 		if VerboseLogs && fr.logReads {
 		if VerboseLogs && fr.logReads {
 			fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
 			fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
 		}
 		}
-		if !httplex.ValidHeaderFieldValue(hf.Value) {
+		if !httpguts.ValidHeaderFieldValue(hf.Value) {
 			invalid = headerFieldValueError(hf.Value)
 			invalid = headerFieldValueError(hf.Value)
 		}
 		}
 		isPseudo := strings.HasPrefix(hf.Name, ":")
 		isPseudo := strings.HasPrefix(hf.Name, ":")

+ 1 - 1
vendor/golang.org/x/net/http2/hpack/encode.go

@@ -206,7 +206,7 @@ func appendVarInt(dst []byte, n byte, i uint64) []byte {
 }
 }
 
 
 // appendHpackString appends s, as encoded in "String Literal"
 // appendHpackString appends s, as encoded in "String Literal"
-// representation, to dst and returns the the extended buffer.
+// representation, to dst and returns the extended buffer.
 //
 //
 // s will be encoded in Huffman codes only when it produces strictly
 // s will be encoded in Huffman codes only when it produces strictly
 // shorter byte string.
 // shorter byte string.

+ 6 - 0
vendor/golang.org/x/net/http2/hpack/hpack.go

@@ -389,6 +389,12 @@ func (d *Decoder) callEmit(hf HeaderField) error {
 
 
 // (same invariants and behavior as parseHeaderFieldRepr)
 // (same invariants and behavior as parseHeaderFieldRepr)
 func (d *Decoder) parseDynamicTableSizeUpdate() error {
 func (d *Decoder) parseDynamicTableSizeUpdate() error {
+	// RFC 7541, sec 4.2: This dynamic table size update MUST occur at the
+	// beginning of the first header block following the change to the dynamic table size.
+	if d.dynTab.size > 0 {
+		return DecodingError{errors.New("dynamic table size update MUST occur at the beginning of a header block")}
+	}
+
 	buf := d.buf
 	buf := d.buf
 	size, buf, err := readVarInt(5, buf)
 	size, buf, err := readVarInt(5, buf)
 	if err != nil {
 	if err != nil {

+ 4 - 4
vendor/golang.org/x/net/http2/http2.go

@@ -29,7 +29,7 @@ import (
 	"strings"
 	"strings"
 	"sync"
 	"sync"
 
 
-	"golang.org/x/net/lex/httplex"
+	"golang.org/x/net/http/httpguts"
 )
 )
 
 
 var (
 var (
@@ -179,7 +179,7 @@ var (
 )
 )
 
 
 // validWireHeaderFieldName reports whether v is a valid header field
 // validWireHeaderFieldName reports whether v is a valid header field
-// name (key). See httplex.ValidHeaderName for the base rules.
+// name (key). See httpguts.ValidHeaderName for the base rules.
 //
 //
 // Further, http2 says:
 // Further, http2 says:
 //   "Just as in HTTP/1.x, header field names are strings of ASCII
 //   "Just as in HTTP/1.x, header field names are strings of ASCII
@@ -191,7 +191,7 @@ func validWireHeaderFieldName(v string) bool {
 		return false
 		return false
 	}
 	}
 	for _, r := range v {
 	for _, r := range v {
-		if !httplex.IsTokenRune(r) {
+		if !httpguts.IsTokenRune(r) {
 			return false
 			return false
 		}
 		}
 		if 'A' <= r && r <= 'Z' {
 		if 'A' <= r && r <= 'Z' {
@@ -312,7 +312,7 @@ func mustUint31(v int32) uint32 {
 }
 }
 
 
 // bodyAllowedForStatus reports whether a given response status code
 // bodyAllowedForStatus reports whether a given response status code
-// permits a body. See RFC 2616, section 4.4.
+// permits a body. See RFC 7230, section 3.3.
 func bodyAllowedForStatus(status int) bool {
 func bodyAllowedForStatus(status int) bool {
 	switch {
 	switch {
 	case status >= 100 && status <= 199:
 	case status >= 100 && status <= 199:

Some files were not shown because too many files changed in this diff