diff --git a/Gopkg.lock b/Gopkg.lock index f433a52af..975c66bfd 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -32,13 +32,13 @@ branch = "master" name = "github.com/ant31/crd-validation" packages = ["pkg"] - revision = "a7560c85183cef6f2e9e912eaf4570bd368ea745" + revision = "eabcf70a1bd73e9296fa0c5f57de604689200a1b" [[projects]] branch = "master" name = "github.com/beorn7/perks" packages = ["quantile"] - revision = "4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9" + revision = "3a771d992973f24aa725d07868b467d1ddfceafb" [[projects]] name = "github.com/blang/semver" @@ -252,8 +252,8 @@ [[projects]] name = "github.com/json-iterator/go" packages = ["."] - revision = "3353055b2a1a5ae1b6a8dfde887a524e7088f3a2" - version = "1.1.2" + revision = "ca39e5af3ece67bbcda3d0f4f56a8e24d9f2dad4" + version = "1.1.3" [[projects]] name = "github.com/juju/ratelimit" @@ -275,7 +275,7 @@ "jlexer", "jwriter" ] - revision = "4a8a4c12c4d1b0c0a7de630426ce6dcb07141b17" + revision = "517203d186eb343d3df4068565cc0446b450d2c4" [[projects]] name = "github.com/matttproud/golang_protobuf_extensions" @@ -348,7 +348,7 @@ "internal/bitbucket.org/ww/goautoneg", "model" ] - revision = "6fb6fce6f8b75884b92e1889c150403fc0872c5e" + revision = "e4aa40a9169a88835b849a6efb71e05dc04b88f0" [[projects]] branch = "master" @@ -359,7 +359,7 @@ "nfs", "xfs" ] - revision = "1c7ff3de94ae006f58cba483a4c9c6d7c61e1d98" + revision = "780932d4fbbe0e69b84c34c20f5c8d0981e109ea" [[projects]] branch = "master" @@ -380,7 +380,7 @@ branch = "master" name = "golang.org/x/crypto" packages = ["ssh/terminal"] - revision = "c7dcf104e3a7a1417abc0230cb0d5240d764159d" + revision = "80db560fac1fb3e6ac81dbc7f8ae4c061f5257bd" [[projects]] branch = "master" @@ -392,13 +392,13 @@ "idna", "lex/httplex" ] - revision = "d0aafc73d5cdc42264b0af071c261abac580695e" + revision = "6078986fec03a1dcc236c34816c71b0e05018fda" [[projects]] branch = "master" name = "golang.org/x/sync" packages = ["errgroup"] - revision = "fd80eb99c8f653c847d294a001bdf2a3a6f768f5" + revision = "1d60e4601c6fd243af51cc01ddf169918a5407ca" [[projects]] branch = "master" @@ -407,7 +407,7 @@ "unix", "windows" ] - revision = "7dca6fe1f43775aa6d1334576870ff63f978f539" + revision = "c488ab1dd8481ef762f96a79a9577c27825be697" [[projects]] name = "golang.org/x/text" @@ -439,7 +439,7 @@ "go/buildutil", "go/loader" ] - revision = "059bec968c61383b574810040ba9410712de36c5" + revision = "2226533658007779ffd629b495a088530c84dc50" [[projects]] name = "gopkg.in/alecthomas/kingpin.v2" @@ -495,7 +495,6 @@ version = "kubernetes-1.9.0" [[projects]] - branch = "master" name = "k8s.io/apiextensions-apiserver" packages = [ "pkg/apis/apiextensions", @@ -504,7 +503,8 @@ "pkg/client/clientset/clientset/scheme", "pkg/client/clientset/clientset/typed/apiextensions/v1beta1" ] - revision = "f7df68b83f2a71fa37ed33c5057553c924b2277a" + revision = "98ecf7bbd60f9f11a72000e4f05203f542136219" + version = "kubernetes-1.9.0" [[projects]] name = "k8s.io/apimachinery" @@ -618,6 +618,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "974708309f89f39c2d96ca1677337cc36a0cfdd4dbc2cbd69a47d870a992470b" + inputs-digest = "c4e63707f13149a6995bc6ac18d596c29ed698f87459304225ec3fde16b32e00" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index a6c04f736..7aad620d0 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -41,8 +41,8 @@ version = "kubernetes-1.9.0" [[constraint]] - branch = "master" name = "k8s.io/apiextensions-apiserver" + version = "kubernetes-1.9.0" [[constraint]] name = "k8s.io/apimachinery" diff --git a/vendor/github.com/ant31/crd-validation/Gopkg.lock b/vendor/github.com/ant31/crd-validation/Gopkg.lock deleted file mode 100644 index 4d068ba3a..000000000 --- a/vendor/github.com/ant31/crd-validation/Gopkg.lock +++ /dev/null @@ -1,191 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - name = "github.com/PuerkitoBio/purell" - packages = ["."] - revision = "0bcb03f4b4d0a9428594752bd2a3b9aa0a9d4bd4" - version = "v1.1.0" - -[[projects]] - branch = "master" - name = "github.com/PuerkitoBio/urlesc" - packages = ["."] - revision = "de5bf2ad457846296e2031421a34e2568e304e35" - -[[projects]] - name = "github.com/emicklei/go-restful" - packages = [ - ".", - "log" - ] - revision = "2dd44038f0b95ae693b266c5f87593b5d2fdd78d" - version = "v2.5.0" - -[[projects]] - name = "github.com/ghodss/yaml" - packages = ["."] - revision = "0ca9ea5df5451ffdf184b4428c902747c2c11cd7" - version = "v1.0.0" - -[[projects]] - branch = "master" - name = "github.com/go-openapi/jsonpointer" - packages = ["."] - revision = "779f45308c19820f1a69e9a4cd965f496e0da10f" - -[[projects]] - branch = "master" - name = "github.com/go-openapi/jsonreference" - packages = ["."] - revision = "36d33bfe519efae5632669801b180bf1a245da3b" - -[[projects]] - branch = "master" - name = "github.com/go-openapi/spec" - packages = ["."] - revision = "fa03337d7da5735229ee8f5e9d5d0b996014b7f8" - -[[projects]] - branch = "master" - name = "github.com/go-openapi/swag" - packages = ["."] - revision = "84f4bee7c0a6db40e3166044c7983c1c32125429" - -[[projects]] - name = "github.com/gogo/protobuf" - packages = [ - "proto", - "sortkeys" - ] - revision = "342cbe0a04158f6dcb03ca0079991a51a4248c02" - version = "v0.5" - -[[projects]] - branch = "master" - name = "github.com/golang/glog" - packages = ["."] - revision = "23def4e6c14b4da8ac2ed8007337bc5eb5007998" - -[[projects]] - branch = "master" - name = "github.com/google/gofuzz" - packages = ["."] - revision = "24818f796faf91cd76ec7bddd72458fbced7a6c1" - -[[projects]] - branch = "master" - name = "github.com/mailru/easyjson" - packages = [ - "buffer", - "jlexer", - "jwriter" - ] - revision = "32fa128f234d041f196a9f3e0fea5ac9772c08e1" - -[[projects]] - name = "github.com/spf13/pflag" - packages = ["."] - revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66" - version = "v1.0.0" - -[[projects]] - branch = "master" - name = "golang.org/x/net" - packages = [ - "http2", - "http2/hpack", - "idna", - "lex/httplex" - ] - revision = "0ed95abb35c445290478a5348a7b38bb154135fd" - -[[projects]] - branch = "master" - name = "golang.org/x/text" - packages = [ - "collate", - "collate/build", - "internal/colltab", - "internal/gen", - "internal/tag", - "internal/triegen", - "internal/ucd", - "language", - "secure/bidirule", - "transform", - "unicode/bidi", - "unicode/cldr", - "unicode/norm", - "unicode/rangetable", - "width" - ] - revision = "e19ae1496984b1c655b8044a65c0300a3c878dd3" - -[[projects]] - name = "gopkg.in/inf.v0" - packages = ["."] - revision = "3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4" - version = "v0.9.0" - -[[projects]] - branch = "v2" - name = "gopkg.in/yaml.v2" - packages = ["."] - revision = "d670f9405373e636a5a2765eea47fac0c9bc91a4" - -[[projects]] - branch = "master" - name = "k8s.io/api" - packages = ["core/v1"] - revision = "dc0dd48d5a5cae9f8736bb0643cfe6052e450f1b" - -[[projects]] - branch = "master" - name = "k8s.io/apiextensions-apiserver" - packages = [ - "pkg/apis/apiextensions", - "pkg/apis/apiextensions/v1beta1" - ] - revision = "ddd9f73609e9a03a76dc8566ba6296db0cda63d3" - -[[projects]] - branch = "master" - name = "k8s.io/apimachinery" - packages = [ - "pkg/api/resource", - "pkg/apis/meta/v1", - "pkg/conversion", - "pkg/conversion/queryparams", - "pkg/fields", - "pkg/labels", - "pkg/runtime", - "pkg/runtime/schema", - "pkg/selection", - "pkg/types", - "pkg/util/errors", - "pkg/util/intstr", - "pkg/util/json", - "pkg/util/net", - "pkg/util/runtime", - "pkg/util/sets", - "pkg/util/validation", - "pkg/util/validation/field", - "pkg/util/wait", - "pkg/watch", - "third_party/forked/golang/reflect" - ] - revision = "b621949a1923cee3fce8bca9613e9a83609f0bbc" - -[[projects]] - branch = "master" - name = "k8s.io/kube-openapi" - packages = ["pkg/common"] - revision = "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "9af3a0bdc9fb071b8a24e4c2320f53398bf7db3bd96b1933811a214e5be8ca3d" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/vendor/github.com/ant31/crd-validation/Gopkg.toml b/vendor/github.com/ant31/crd-validation/Gopkg.toml deleted file mode 100644 index fdc9a6d19..000000000 --- a/vendor/github.com/ant31/crd-validation/Gopkg.toml +++ /dev/null @@ -1,33 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" - - -[[constraint]] - branch = "master" - name = "github.com/go-openapi/spec" - -[[constraint]] - branch = "master" - name = "k8s.io/apiextensions-apiserver" - -[[constraint]] - branch = "master" - name = "k8s.io/kube-openapi" diff --git a/vendor/github.com/beorn7/perks/quantile/stream.go b/vendor/github.com/beorn7/perks/quantile/stream.go index f4cabd669..d7d14f8eb 100644 --- a/vendor/github.com/beorn7/perks/quantile/stream.go +++ b/vendor/github.com/beorn7/perks/quantile/stream.go @@ -77,15 +77,20 @@ func NewHighBiased(epsilon float64) *Stream { // is guaranteed to be within (Quantile±Epsilon). // // 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 { var m = math.MaxFloat64 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 { - f = (2 * epsilon * (s.n - r)) / (1 - quantile) + f = (2 * t.epsilon * (s.n - r)) / (1 - t.quantile) } if f < m { m = f @@ -96,6 +101,25 @@ func NewTargeted(targets map[float64]float64) *Stream { 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 // design. Take care when using across multiple goroutines. type Stream struct { diff --git a/vendor/github.com/json-iterator/go/config.go b/vendor/github.com/json-iterator/go/config.go index b69cdbfc3..bd66947d7 100644 --- a/vendor/github.com/json-iterator/go/config.go +++ b/vendor/github.com/json-iterator/go/config.go @@ -2,11 +2,12 @@ package jsoniter import ( "encoding/json" + "github.com/modern-go/concurrent" "github.com/modern-go/reflect2" "io" + "reflect" "sync" "unsafe" - "github.com/modern-go/concurrent" ) // Config customize how the API should behave. @@ -39,6 +40,8 @@ type API interface { NewDecoder(reader io.Reader) *Decoder Valid(data []byte) bool RegisterExtension(extension Extension) + DecoderOf(typ reflect2.Type) ValDecoder + EncoderOf(typ reflect2.Type) ValEncoder } // ConfigDefault the default API @@ -60,7 +63,6 @@ var ConfigFastest = Config{ ObjectFieldMustBeSimpleString: true, // do not unescape object field }.Froze() - type frozenConfig struct { configBeforeFrozen Config sortMapKeys bool @@ -104,7 +106,7 @@ func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder { return nil } -var cfgCache = &sync.Map{} +var cfgCache = concurrent.NewMap() func getFrozenConfigFromCache(cfg Config) *frozenConfig { obj, found := cfgCache.Load(cfg) @@ -192,6 +194,11 @@ func (cfg *frozenConfig) validateJsonRawMessage(extension EncoderExtension) { func (cfg *frozenConfig) useNumber(extension DecoderExtension) { extension[reflect2.TypeOfPtr((*interface{})(nil)).Elem()] = &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) { + exitingValue := *((*interface{})(ptr)) + if exitingValue != nil && reflect.TypeOf(exitingValue).Kind() == reflect.Ptr { + iter.ReadVal(exitingValue) + return + } if iter.WhatIsNext() == NumberValue { *((*interface{})(ptr)) = json.Number(iter.readNumberAsString()) } else { diff --git a/vendor/github.com/json-iterator/go/extension_tests/extension_test.go b/vendor/github.com/json-iterator/go/extension_tests/extension_test.go index 043379ea4..836db5bc0 100644 --- a/vendor/github.com/json-iterator/go/extension_tests/extension_test.go +++ b/vendor/github.com/json-iterator/go/extension_tests/extension_test.go @@ -2,8 +2,8 @@ package test import ( "github.com/json-iterator/go" - "github.com/stretchr/testify/require" "github.com/modern-go/reflect2" + "github.com/stretchr/testify/require" "reflect" "strconv" "testing" diff --git a/vendor/github.com/json-iterator/go/extra/binary_as_string_codec.go b/vendor/github.com/json-iterator/go/extra/binary_as_string_codec.go index f9d8b7502..543895bef 100644 --- a/vendor/github.com/json-iterator/go/extra/binary_as_string_codec.go +++ b/vendor/github.com/json-iterator/go/extra/binary_as_string_codec.go @@ -2,9 +2,9 @@ package extra import ( "github.com/json-iterator/go" - "unsafe" - "unicode/utf8" "github.com/modern-go/reflect2" + "unicode/utf8" + "unsafe" ) // safeSet holds the value true if the ASCII character with the given array @@ -171,18 +171,18 @@ func (codec *binaryAsStringCodec) Encode(ptr unsafe.Pointer, stream *jsoniter.St func readHex(iter *jsoniter.Iterator, b1, b2 byte) byte { var ret byte if b1 >= '0' && b1 <= '9' { - ret = b1-'0' + ret = b1 - '0' } else if b1 >= 'a' && b1 <= 'f' { - ret = b1-'a'+10 + ret = b1 - 'a' + 10 } else { iter.ReportError("read hex", "expects 0~9 or a~f, but found "+string([]byte{b1})) return 0 } ret = ret * 16 if b2 >= '0' && b2 <= '9' { - ret = b2-'0' + ret = b2 - '0' } else if b2 >= 'a' && b2 <= 'f' { - ret = b2-'a'+10 + ret = b2 - 'a' + 10 } else { iter.ReportError("read hex", "expects 0~9 or a~f, but found "+string([]byte{b2})) return 0 diff --git a/vendor/github.com/json-iterator/go/extra/binary_as_string_codec_test.go b/vendor/github.com/json-iterator/go/extra/binary_as_string_codec_test.go index d67716810..a00479e6c 100644 --- a/vendor/github.com/json-iterator/go/extra/binary_as_string_codec_test.go +++ b/vendor/github.com/json-iterator/go/extra/binary_as_string_codec_test.go @@ -1,9 +1,9 @@ package extra import ( - "testing" - "github.com/stretchr/testify/require" "github.com/json-iterator/go" + "github.com/stretchr/testify/require" + "testing" ) func init() { diff --git a/vendor/github.com/json-iterator/go/misc_tests/jsoniter_map_test.go b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_map_test.go index 3f594b29c..b0dde94cf 100644 --- a/vendor/github.com/json-iterator/go/misc_tests/jsoniter_map_test.go +++ b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_map_test.go @@ -31,3 +31,14 @@ func Test_read_map_with_reader(t *testing.T) { should.Equal(m2, m1) should.Equal("1.0.76", m1["note"].(map[string]interface{})["CoreServices"].(map[string]interface{})["version_name"]) } + +func Test_map_eface_of_eface(t *testing.T) { + should := require.New(t) + json := jsoniter.ConfigCompatibleWithStandardLibrary + output, err := json.MarshalToString(map[interface{}]interface{}{ + "1": 2, + 3: "4", + }) + should.NoError(err) + should.Equal(`{"1":2,"3":"4"}`, output) +} diff --git a/vendor/github.com/json-iterator/go/misc_tests/jsoniter_object_test.go b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_object_test.go index 0ffc207a7..e44b66f05 100644 --- a/vendor/github.com/json-iterator/go/misc_tests/jsoniter_object_test.go +++ b/vendor/github.com/json-iterator/go/misc_tests/jsoniter_object_test.go @@ -130,3 +130,20 @@ func Test_reader_and_load_more(t *testing.T) { obj := TestObject{} should.Nil(decoder.Decode(&obj)) } + +func Test_unmarshal_into_existing_value(t *testing.T) { + should := require.New(t) + type TestObject struct { + Field1 int + Field2 interface{} + } + var obj TestObject + m := map[string]interface{}{} + obj.Field2 = &m + cfg := jsoniter.Config{UseNumber: true}.Froze() + err := cfg.Unmarshal([]byte(`{"Field1":1,"Field2":{"k":"v"}}`), &obj) + should.NoError(err) + should.Equal(map[string]interface{}{ + "k": "v", + }, m) +} diff --git a/vendor/github.com/json-iterator/go/reflect_map.go b/vendor/github.com/json-iterator/go/reflect_map.go index f34d519f9..8812f0850 100644 --- a/vendor/github.com/json-iterator/go/reflect_map.go +++ b/vendor/github.com/json-iterator/go/reflect_map.go @@ -3,6 +3,7 @@ package jsoniter import ( "fmt" "github.com/modern-go/reflect2" + "io" "reflect" "sort" "unsafe" @@ -107,6 +108,9 @@ func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder { stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), } } + if typ.Kind() == reflect.Interface { + return &dynamicMapKeyEncoder{ctx, typ} + } return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)} } } @@ -203,6 +207,21 @@ func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool { return false } +type dynamicMapKeyEncoder struct { + ctx *ctx + valType reflect2.Type +} + +func (encoder *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := encoder.valType.UnsafeIndirect(ptr) + encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream) +} + +func (encoder *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool { + obj := encoder.valType.UnsafeIndirect(ptr) + return encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj)) +} + type mapEncoder struct { mapType *reflect2.UnsafeMapType keyEncoder ValEncoder @@ -253,6 +272,9 @@ func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { subStream.buf = make([]byte, 0, 64) key, elem := mapIter.UnsafeNext() encoder.keyEncoder.Encode(key, subStream) + if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil { + stream.Error = subStream.Error + } encodedKey := subStream.Buffer() subIter.ResetBytes(encodedKey) decodedKey := subIter.ReadString() diff --git a/vendor/github.com/json-iterator/go/value_tests/slice_test.go b/vendor/github.com/json-iterator/go/value_tests/slice_test.go index 3e4c34840..f504e851e 100644 --- a/vendor/github.com/json-iterator/go/value_tests/slice_test.go +++ b/vendor/github.com/json-iterator/go/value_tests/slice_test.go @@ -6,7 +6,7 @@ func init() { []interface{}{"hello"}, nilSlice, &nilSlice, - selectedMarshalCase{[]byte{1,2,3}}, + []byte{1, 2, 3}, ) unmarshalCases = append(unmarshalCases, unmarshalCase{ ptr: (*[]string)(nil), @@ -20,6 +20,5 @@ func init() { }, unmarshalCase{ ptr: (*[]byte)(nil), input: `"aGVsbG8="`, - selected: true, }) } diff --git a/vendor/github.com/json-iterator/go/value_tests/value_test.go b/vendor/github.com/json-iterator/go/value_tests/value_test.go index ec1bed77f..95cfdd568 100644 --- a/vendor/github.com/json-iterator/go/value_tests/value_test.go +++ b/vendor/github.com/json-iterator/go/value_tests/value_test.go @@ -4,8 +4,8 @@ import ( "encoding/json" "fmt" "github.com/json-iterator/go" - "github.com/stretchr/testify/require" "github.com/modern-go/reflect2" + "github.com/stretchr/testify/require" "testing" ) diff --git a/vendor/github.com/mailru/easyjson/gen/decoder.go b/vendor/github.com/mailru/easyjson/gen/decoder.go index f740c68c2..3c8f8f8d0 100644 --- a/vendor/github.com/mailru/easyjson/gen/decoder.go +++ b/vendor/github.com/mailru/easyjson/gen/decoder.go @@ -48,10 +48,12 @@ var primitiveStringDecoders = map[reflect.Kind]string{ reflect.Uint32: "in.Uint32Str()", reflect.Uint64: "in.Uint64Str()", reflect.Uintptr: "in.UintptrStr()", + reflect.Float32: "in.Float32Str()", + reflect.Float64: "in.Float64Str()", } var customDecoders = map[string]string{ - "json.Number": "in.JsonNumber()", + "json.Number": "in.JsonNumber()", } // genTypeDecoder generates decoding code for the type t, but uses unmarshaler interface if implemented by t. @@ -96,7 +98,7 @@ func hasCustomUnmarshaler(t reflect.Type) bool { func (g *Generator) genTypeDecoderNoCheck(t reflect.Type, out string, tags fieldTags, indent int) error { ws := strings.Repeat(" ", indent) // Check whether type is primitive, needs to be done after interface check. - if dec := customDecoders[t.String()]; dec != "" { + if dec := customDecoders[t.String()]; dec != "" { fmt.Fprintln(g.out, ws+out+" = "+dec) return nil } else if dec := primitiveStringDecoders[t.Kind()]; dec != "" && tags.asString { @@ -178,7 +180,7 @@ func (g *Generator) genTypeDecoderNoCheck(t reflect.Type, out string, tags field fmt.Fprintln(g.out, ws+" for !in.IsDelim(']') {") fmt.Fprintln(g.out, ws+" if "+iterVar+" < "+fmt.Sprint(length)+" {") - if err := g.genTypeDecoder(elem, out+"["+iterVar+"]", tags, indent+3); err != nil { + if err := g.genTypeDecoder(elem, "("+out+")["+iterVar+"]", tags, indent+3); err != nil { return err } diff --git a/vendor/github.com/mailru/easyjson/gen/encoder.go b/vendor/github.com/mailru/easyjson/gen/encoder.go index 4eca16015..293a66a47 100644 --- a/vendor/github.com/mailru/easyjson/gen/encoder.go +++ b/vendor/github.com/mailru/easyjson/gen/encoder.go @@ -45,6 +45,8 @@ var primitiveStringEncoders = map[reflect.Kind]string{ reflect.Uint32: "out.Uint32Str(uint32(%v))", reflect.Uint64: "out.Uint64Str(uint64(%v))", reflect.Uintptr: "out.UintptrStr(uintptr(%v))", + reflect.Float32: "out.Float32Str(float32(%v))", + reflect.Float64: "out.Float64Str(float64(%v))", } // fieldTags contains parsed version of json struct field tags. @@ -173,7 +175,7 @@ func (g *Generator) genTypeEncoderNoCheck(t reflect.Type, in string, tags fieldT fmt.Fprintln(g.out, ws+" out.RawByte(',')") fmt.Fprintln(g.out, ws+" }") - if err := g.genTypeEncoder(elem, in+"["+iVar+"]", tags, indent+1, false); err != nil { + if err := g.genTypeEncoder(elem, "("+in+")["+iVar+"]", tags, indent+1, false); err != nil { return err } diff --git a/vendor/github.com/mailru/easyjson/jlexer/lexer.go b/vendor/github.com/mailru/easyjson/jlexer/lexer.go index e5558ae39..18d65cd5a 100644 --- a/vendor/github.com/mailru/easyjson/jlexer/lexer.go +++ b/vendor/github.com/mailru/easyjson/jlexer/lexer.go @@ -997,6 +997,22 @@ func (r *Lexer) Float32() float32 { return float32(n) } +func (r *Lexer) Float32Str() float32 { + s, b := r.unsafeString() + if !r.Ok() { + return 0 + } + n, err := strconv.ParseFloat(s, 32) + if err != nil { + r.addNonfatalError(&LexerError{ + Offset: r.start, + Reason: err.Error(), + Data: string(b), + }) + } + return float32(n) +} + func (r *Lexer) Float64() float64 { s := r.number() if !r.Ok() { @@ -1014,6 +1030,22 @@ func (r *Lexer) Float64() float64 { return n } +func (r *Lexer) Float64Str() float64 { + s, b := r.unsafeString() + if !r.Ok() { + return 0 + } + n, err := strconv.ParseFloat(s, 64) + if err != nil { + r.addNonfatalError(&LexerError{ + Offset: r.start, + Reason: err.Error(), + Data: string(b), + }) + } + return n +} + func (r *Lexer) Error() error { return r.fatalError } diff --git a/vendor/github.com/mailru/easyjson/jwriter/writer.go b/vendor/github.com/mailru/easyjson/jwriter/writer.go index e5a5ddfdb..b9ed7ccaa 100644 --- a/vendor/github.com/mailru/easyjson/jwriter/writer.go +++ b/vendor/github.com/mailru/easyjson/jwriter/writer.go @@ -240,11 +240,25 @@ func (w *Writer) Float32(n float32) { w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 32) } +func (w *Writer) Float32Str(n float32) { + w.Buffer.EnsureSpace(20) + w.Buffer.Buf = append(w.Buffer.Buf, '"') + w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 32) + w.Buffer.Buf = append(w.Buffer.Buf, '"') +} + func (w *Writer) Float64(n float64) { w.Buffer.EnsureSpace(20) w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, n, 'g', -1, 64) } +func (w *Writer) Float64Str(n float64) { + w.Buffer.EnsureSpace(20) + w.Buffer.Buf = append(w.Buffer.Buf, '"') + w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 64) + w.Buffer.Buf = append(w.Buffer.Buf, '"') +} + func (w *Writer) Bool(v bool) { w.Buffer.EnsureSpace(5) if v { @@ -340,12 +354,11 @@ func (w *Writer) base64(in []byte) { return } - w.Buffer.EnsureSpace(((len(in) - 1) / 3 + 1) * 4) + w.Buffer.EnsureSpace(((len(in)-1)/3 + 1) * 4) si := 0 n := (len(in) / 3) * 3 - for si < n { // Convert 3x 8bit source bytes into 4 bytes val := uint(in[si+0])<<16 | uint(in[si+1])<<8 | uint(in[si+2]) diff --git a/vendor/github.com/mailru/easyjson/tests/basic_test.go b/vendor/github.com/mailru/easyjson/tests/basic_test.go index 64649c47c..28f0fdf25 100644 --- a/vendor/github.com/mailru/easyjson/tests/basic_test.go +++ b/vendor/github.com/mailru/easyjson/tests/basic_test.go @@ -49,6 +49,7 @@ var testCases = []struct { {&mapUint64StringValue, mapUint64StringValueString}, {&mapUintptrStringValue, mapUintptrStringValueString}, {&intKeyedMapStructValue, intKeyedMapStructValueString}, + {&intArrayStructValue, intArrayStructValueString}, } func TestMarshal(t *testing.T) { diff --git a/vendor/github.com/mailru/easyjson/tests/data.go b/vendor/github.com/mailru/easyjson/tests/data.go index 145f093d6..8d5132d51 100644 --- a/vendor/github.com/mailru/easyjson/tests/data.go +++ b/vendor/github.com/mailru/easyjson/tests/data.go @@ -41,6 +41,9 @@ type PrimitiveTypes struct { Float32 float32 Float64 float64 + Float32String float32 `json:",string"` + Float64String float64 `json:",string"` + Ptr *string PtrNil *string } @@ -77,6 +80,9 @@ var primitiveTypesValue = PrimitiveTypes{ Float32: 1.5, Float64: math.MaxFloat64, + Float32String: 1.5, + Float64String: math.MaxFloat64, + Ptr: &str, } @@ -110,6 +116,9 @@ var primitiveTypesString = "{" + `"Float32":` + fmt.Sprint(1.5) + `,` + `"Float64":` + fmt.Sprint(math.MaxFloat64) + `,` + + `"Float32String":"` + fmt.Sprint(1.5) + `",` + + `"Float64String":"` + fmt.Sprint(math.MaxFloat64) + `",` + + `"Ptr":"bla",` + `"PtrNil":null` + @@ -757,3 +766,21 @@ var intKeyedMapStructValueString = `{` + `"foo":{"42":"life"},` + `"bar":{"32":{"354634382":"life"}}` + `}` + +type IntArray [2]int + +//easyjson:json +type IntArrayStruct struct { + Pointer *IntArray `json:"pointer"` + Value IntArray `json:"value"` +} + +var intArrayStructValue = IntArrayStruct{ + Pointer: &IntArray{1, 2}, + Value: IntArray{1, 2}, +} + +var intArrayStructValueString = `{` + + `"pointer":[1,2],` + + `"value":[1,2]` + + `}` diff --git a/vendor/github.com/prometheus/common/route/route.go b/vendor/github.com/prometheus/common/route/route.go index bb4688173..dbec638e5 100644 --- a/vendor/github.com/prometheus/common/route/route.go +++ b/vendor/github.com/prometheus/common/route/route.go @@ -19,11 +19,12 @@ func WithParam(ctx context.Context, p, v string) context.Context { return context.WithValue(ctx, param(p), v) } -// Router wraps httprouter.Router and adds support for prefixed sub-routers -// and per-request context injections. +// Router wraps httprouter.Router and adds support for prefixed sub-routers, +// per-request context injections and instrumentation. type Router struct { rtr *httprouter.Router prefix string + instrh func(handlerName string, handler http.HandlerFunc) http.HandlerFunc } // New returns a new Router. @@ -33,13 +34,18 @@ func New() *Router { } } +// WithInstrumentation returns a router with instrumentation support. +func (r *Router) WithInstrumentation(instrh func(handlerName string, handler http.HandlerFunc) http.HandlerFunc) *Router { + return &Router{rtr: r.rtr, prefix: r.prefix, instrh: instrh} +} + // WithPrefix returns a router that prefixes all registered routes with prefix. func (r *Router) WithPrefix(prefix string) *Router { - return &Router{rtr: r.rtr, prefix: r.prefix + prefix} + return &Router{rtr: r.rtr, prefix: r.prefix + prefix, instrh: r.instrh} } // handle turns a HandlerFunc into an httprouter.Handle. -func (r *Router) handle(h http.HandlerFunc) httprouter.Handle { +func (r *Router) handle(handlerName string, h http.HandlerFunc) httprouter.Handle { return func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -47,33 +53,36 @@ func (r *Router) handle(h http.HandlerFunc) httprouter.Handle { for _, p := range params { ctx = context.WithValue(ctx, param(p.Key), p.Value) } + if r.instrh != nil { + h = r.instrh(handlerName, h) + } h(w, req.WithContext(ctx)) } } // Get registers a new GET route. func (r *Router) Get(path string, h http.HandlerFunc) { - r.rtr.GET(r.prefix+path, r.handle(h)) + r.rtr.GET(r.prefix+path, r.handle(path, h)) } // Options registers a new OPTIONS route. func (r *Router) Options(path string, h http.HandlerFunc) { - r.rtr.OPTIONS(r.prefix+path, r.handle(h)) + r.rtr.OPTIONS(r.prefix+path, r.handle(path, h)) } // Del registers a new DELETE route. func (r *Router) Del(path string, h http.HandlerFunc) { - r.rtr.DELETE(r.prefix+path, r.handle(h)) + r.rtr.DELETE(r.prefix+path, r.handle(path, h)) } // Put registers a new PUT route. func (r *Router) Put(path string, h http.HandlerFunc) { - r.rtr.PUT(r.prefix+path, r.handle(h)) + r.rtr.PUT(r.prefix+path, r.handle(path, h)) } // Post registers a new POST route. func (r *Router) Post(path string, h http.HandlerFunc) { - r.rtr.POST(r.prefix+path, r.handle(h)) + r.rtr.POST(r.prefix+path, r.handle(path, h)) } // Redirect takes an absolute path and sends an internal HTTP redirect for it, diff --git a/vendor/github.com/prometheus/common/route/route_test.go b/vendor/github.com/prometheus/common/route/route_test.go index a9bb20996..d491cad66 100644 --- a/vendor/github.com/prometheus/common/route/route_test.go +++ b/vendor/github.com/prometheus/common/route/route_test.go @@ -42,3 +42,35 @@ func TestContext(t *testing.T) { } router.ServeHTTP(nil, r) } + +func TestInstrumentation(t *testing.T) { + var got string + cases := []struct { + router *Router + want string + }{ + { + router: New(), + want: "", + }, { + router: New().WithInstrumentation(func(handlerName string, handler http.HandlerFunc) http.HandlerFunc { + got = handlerName + return handler + }), + want: "/foo", + }, + } + + for _, c := range cases { + c.router.Get("/foo", func(w http.ResponseWriter, r *http.Request) {}) + + r, err := http.NewRequest("GET", "http://localhost:9090/foo", nil) + if err != nil { + t.Fatalf("Error building test request: %s", err) + } + c.router.ServeHTTP(nil, r) + if c.want != got { + t.Fatalf("Unexpected value: want %q, got %q", c.want, got) + } + } +} diff --git a/vendor/github.com/prometheus/procfs/nfs/nfs.go b/vendor/github.com/prometheus/procfs/nfs/nfs.go index e2185b782..651bf6819 100644 --- a/vendor/github.com/prometheus/procfs/nfs/nfs.go +++ b/vendor/github.com/prometheus/procfs/nfs/nfs.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package nfsd implements parsing of /proc/net/rpc/nfsd. +// Package nfs implements parsing of /proc/net/rpc/nfsd. // Fields are documented in https://www.svennd.be/nfsd-stats-explained-procnetrpcnfsd/ package nfs @@ -136,8 +136,8 @@ type ClientV4Stats struct { Setattr uint64 FsInfo uint64 Renew uint64 - SetClientId uint64 - SetClientIdConfirm uint64 + SetClientID uint64 + SetClientIDConfirm uint64 Lock uint64 Lockt uint64 Locku uint64 @@ -156,13 +156,13 @@ type ClientV4Stats struct { ReadDir uint64 ServerCaps uint64 DelegReturn uint64 - GetAcl uint64 - SetAcl uint64 + GetACL uint64 + SetACL uint64 FsLocations uint64 ReleaseLockowner uint64 Secinfo uint64 FsidPresent uint64 - ExchangeId uint64 + ExchangeID uint64 CreateSession uint64 DestroySession uint64 Sequence uint64 @@ -173,11 +173,11 @@ type ClientV4Stats struct { LayoutCommit uint64 LayoutReturn uint64 SecinfoNoName uint64 - TestStateId uint64 - FreeStateId uint64 + TestStateID uint64 + FreeStateID uint64 GetDeviceList uint64 BindConnToSession uint64 - DestroyClientId uint64 + DestroyClientID uint64 Seek uint64 Allocate uint64 DeAllocate uint64 @@ -238,7 +238,7 @@ type V4Ops struct { RelLockOwner uint64 } -// RPCStats models all stats from /proc/net/rpc/nfs. +// ClientRPCStats models all stats from /proc/net/rpc/nfs. type ClientRPCStats struct { Network Network ClientRPC ClientRPC diff --git a/vendor/github.com/prometheus/procfs/nfs/parse.go b/vendor/github.com/prometheus/procfs/nfs/parse.go index 8f568f011..95a83cc5b 100644 --- a/vendor/github.com/prometheus/procfs/nfs/parse.go +++ b/vendor/github.com/prometheus/procfs/nfs/parse.go @@ -204,8 +204,8 @@ func parseClientV4Stats(v []uint64) (ClientV4Stats, error) { Setattr: v[10], FsInfo: v[11], Renew: v[12], - SetClientId: v[13], - SetClientIdConfirm: v[14], + SetClientID: v[13], + SetClientIDConfirm: v[14], Lock: v[15], Lockt: v[16], Locku: v[17], @@ -224,13 +224,13 @@ func parseClientV4Stats(v []uint64) (ClientV4Stats, error) { ReadDir: v[30], ServerCaps: v[31], DelegReturn: v[32], - GetAcl: v[33], - SetAcl: v[34], + GetACL: v[33], + SetACL: v[34], FsLocations: v[35], ReleaseLockowner: v[36], Secinfo: v[37], FsidPresent: v[38], - ExchangeId: v[39], + ExchangeID: v[39], CreateSession: v[40], DestroySession: v[41], Sequence: v[42], @@ -241,11 +241,11 @@ func parseClientV4Stats(v []uint64) (ClientV4Stats, error) { LayoutCommit: v[47], LayoutReturn: v[48], SecinfoNoName: v[49], - TestStateId: v[50], - FreeStateId: v[51], + TestStateID: v[50], + FreeStateID: v[51], GetDeviceList: v[52], BindConnToSession: v[53], - DestroyClientId: v[54], + DestroyClientID: v[54], Seek: v[55], Allocate: v[56], DeAllocate: v[57], diff --git a/vendor/github.com/prometheus/procfs/nfs/parse_nfs_test.go b/vendor/github.com/prometheus/procfs/nfs/parse_nfs_test.go index 372f9be3d..8ebcfd16e 100644 --- a/vendor/github.com/prometheus/procfs/nfs/parse_nfs_test.go +++ b/vendor/github.com/prometheus/procfs/nfs/parse_nfs_test.go @@ -108,8 +108,8 @@ proc4 48 98 51 54 83 85 23 24 1 28 73 68 83 12 84 39 68 59 58 88 29 74 69 96 21 Setattr: 73, FsInfo: 68, Renew: 83, - SetClientId: 12, - SetClientIdConfirm: 84, + SetClientID: 12, + SetClientIDConfirm: 84, Lock: 39, Lockt: 68, Locku: 59, @@ -128,13 +128,13 @@ proc4 48 98 51 54 83 85 23 24 1 28 73 68 83 12 84 39 68 59 58 88 29 74 69 96 21 ReadDir: 66, ServerCaps: 56, DelegReturn: 97, - GetAcl: 36, - SetAcl: 49, + GetACL: 36, + SetACL: 49, FsLocations: 32, ReleaseLockowner: 85, Secinfo: 81, FsidPresent: 11, - ExchangeId: 58, + ExchangeID: 58, CreateSession: 32, DestroySession: 67, Sequence: 13, @@ -145,11 +145,11 @@ proc4 48 98 51 54 83 85 23 24 1 28 73 68 83 12 84 39 68 59 58 88 29 74 69 96 21 LayoutCommit: 26, LayoutReturn: 1337, SecinfoNoName: 0, - TestStateId: 0, - FreeStateId: 0, + TestStateID: 0, + FreeStateID: 0, GetDeviceList: 0, BindConnToSession: 0, - DestroyClientId: 0, + DestroyClientID: 0, Seek: 0, Allocate: 0, DeAllocate: 0, @@ -234,8 +234,8 @@ proc4 61 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Setattr: 0, FsInfo: 0, Renew: 0, - SetClientId: 1, - SetClientIdConfirm: 1, + SetClientID: 1, + SetClientIDConfirm: 1, Lock: 0, Lockt: 0, Locku: 0, @@ -254,13 +254,13 @@ proc4 61 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ReadDir: 0, ServerCaps: 0, DelegReturn: 0, - GetAcl: 0, - SetAcl: 0, + GetACL: 0, + SetACL: 0, FsLocations: 0, ReleaseLockowner: 0, Secinfo: 0, FsidPresent: 0, - ExchangeId: 0, + ExchangeID: 0, CreateSession: 0, DestroySession: 0, Sequence: 0, @@ -271,11 +271,11 @@ proc4 61 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 LayoutCommit: 0, LayoutReturn: 0, SecinfoNoName: 0, - TestStateId: 0, - FreeStateId: 0, + TestStateID: 0, + FreeStateID: 0, GetDeviceList: 0, BindConnToSession: 0, - DestroyClientId: 0, + DestroyClientID: 0, Seek: 0, Allocate: 0, DeAllocate: 0, diff --git a/vendor/github.com/prometheus/procfs/ttar b/vendor/github.com/prometheus/procfs/ttar index b514e7312..b0171a12b 100755 --- a/vendor/github.com/prometheus/procfs/ttar +++ b/vendor/github.com/prometheus/procfs/ttar @@ -229,13 +229,13 @@ function extract { # The repeated pattern makes up for sed's lack of negative # lookbehind assertions (for consecutive null bytes). echo -n "$line" | \ - sed 's/^NULLBYTE/\x0/g' | \ - sed 's/\([^\\]\)NULLBYTE/\1\x0/g' | \ - sed 's/\([^\\]\)NULLBYTE/\1\x0/g' | \ - sed 's/\\NULLBYTE/NULLBYTE/g' | \ - sed 's/\([^\\]\)EOF/\1/g' | \ - sed 's/\\EOF/EOF/g' \ - >> "$path" + sed -e 's/^NULLBYTE/\x0/g; + s/\([^\\]\)NULLBYTE/\1\x0/g; + s/\([^\\]\)NULLBYTE/\1\x0/g; + s/\\NULLBYTE/NULLBYTE/g; + s/\([^\\]\)EOF/\1/g; + s/\\EOF/EOF/g; + ' >> "$path" fi if [[ "$eof_without_newline" -eq 0 ]]; then echo >> "$path" @@ -283,11 +283,14 @@ function get_mode { local mfile=$1 if [ -z "${STAT_OPTION:-}" ]; then if stat -c '%a' "$mfile" >/dev/null 2>&1; then + # GNU stat STAT_OPTION='-c' STAT_FORMAT='%a' else + # BSD stat STAT_OPTION='-f' - STAT_FORMAT='%A' + # Octal output, user/group/other (omit file type, sticky bit) + STAT_FORMAT='%OLp' fi fi stat "${STAT_OPTION}" "${STAT_FORMAT}" "$mfile" @@ -334,9 +337,10 @@ function _create { < "$file" python -c "$PYTHON_CREATE_FILTER" else < "$file" \ - sed 's/EOF/\\EOF/g' | \ - sed 's/NULLBYTE/\\NULLBYTE/g' | \ - sed 's/\x0/NULLBYTE/g' + sed 's/EOF/\\EOF/g; + s/NULLBYTE/\\NULLBYTE/g; + s/\x0/NULLBYTE/g; + ' fi if [[ "$eof_without_newline" -eq 1 ]]; then # Finish line with EOF to indicate that the original line did diff --git a/vendor/golang.org/x/crypto/CONTRIBUTING.md b/vendor/golang.org/x/crypto/CONTRIBUTING.md index 88dff59bc..d0485e887 100644 --- a/vendor/golang.org/x/crypto/CONTRIBUTING.md +++ b/vendor/golang.org/x/crypto/CONTRIBUTING.md @@ -4,16 +4,15 @@ Go is an open source project. It is the work of hundreds of contributors. We appreciate your help! - ## Filing issues When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions: -1. What version of Go are you using (`go version`)? -2. What operating system and processor architecture are you using? -3. What did you do? -4. What did you expect to see? -5. What did you see instead? +1. What version of Go are you using (`go version`)? +2. What operating system and processor architecture are you using? +3. What did you do? +4. What did you expect to see? +5. What did you see instead? General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker. The gophers there will answer or ask you to file an issue if you've tripped over a bug. @@ -23,9 +22,5 @@ The gophers there will answer or ask you to file an issue if you've tripped over Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) before sending patches. -**We do not accept GitHub pull requests** -(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review). - Unless otherwise noted, the Go source files are distributed under the BSD-style license found in the LICENSE file. - diff --git a/vendor/golang.org/x/crypto/acme/autocert/renewal.go b/vendor/golang.org/x/crypto/acme/autocert/renewal.go index 2a3a0a706..3fa4d61a2 100644 --- a/vendor/golang.org/x/crypto/acme/autocert/renewal.go +++ b/vendor/golang.org/x/crypto/acme/autocert/renewal.go @@ -71,12 +71,21 @@ func (dr *domainRenewal) renew() { testDidRenewLoop(next, err) } +// updateState locks and replaces the relevant Manager.state item with the given +// state. It additionally updates dr.key with the given state's key. +func (dr *domainRenewal) updateState(state *certState) { + dr.m.stateMu.Lock() + defer dr.m.stateMu.Unlock() + dr.key = state.key + dr.m.state[dr.domain] = state +} + // do is similar to Manager.createCert but it doesn't lock a Manager.state item. // Instead, it requests a new certificate independently and, upon success, // replaces dr.m.state item with a new one and updates cache for the given domain. // -// It may return immediately if the expiration date of the currently cached cert -// is far enough in the future. +// It may lock and update the Manager.state if the expiration date of the currently +// cached cert is far enough in the future. // // The returned value is a time interval after which the renewal should occur again. func (dr *domainRenewal) do(ctx context.Context) (time.Duration, error) { @@ -85,7 +94,16 @@ func (dr *domainRenewal) do(ctx context.Context) (time.Duration, error) { if tlscert, err := dr.m.cacheGet(ctx, dr.domain); err == nil { next := dr.next(tlscert.Leaf.NotAfter) if next > dr.m.renewBefore()+renewJitter { - return next, nil + signer, ok := tlscert.PrivateKey.(crypto.Signer) + if ok { + state := &certState{ + key: signer, + cert: tlscert.Certificate, + leaf: tlscert.Leaf, + } + dr.updateState(state) + return next, nil + } } } @@ -105,10 +123,7 @@ func (dr *domainRenewal) do(ctx context.Context) (time.Duration, error) { if err := dr.m.cachePut(ctx, dr.domain, tlscert); err != nil { return 0, err } - dr.m.stateMu.Lock() - defer dr.m.stateMu.Unlock() - // m.state is guaranteed to be non-nil at this point - dr.m.state[dr.domain] = state + dr.updateState(state) return dr.next(leaf.NotAfter), nil } diff --git a/vendor/golang.org/x/crypto/acme/autocert/renewal_test.go b/vendor/golang.org/x/crypto/acme/autocert/renewal_test.go index 11d40ff5d..6e88672bd 100644 --- a/vendor/golang.org/x/crypto/acme/autocert/renewal_test.go +++ b/vendor/golang.org/x/crypto/acme/autocert/renewal_test.go @@ -189,3 +189,149 @@ func TestRenewFromCache(t *testing.T) { case <-done: } } + +func TestRenewFromCacheAlreadyRenewed(t *testing.T) { + const domain = "example.org" + + // use EC key to run faster on 386 + key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + t.Fatal(err) + } + man := &Manager{ + Prompt: AcceptTOS, + Cache: newMemCache(), + RenewBefore: 24 * time.Hour, + Client: &acme.Client{ + Key: key, + DirectoryURL: "invalid", + }, + } + defer man.stopRenew() + + // cache a recently renewed cert with a different private key + newKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + t.Fatal(err) + } + now := time.Now() + newCert, err := dateDummyCert(newKey.Public(), now.Add(-2*time.Hour), now.Add(time.Hour*24*90), domain) + if err != nil { + t.Fatal(err) + } + newLeaf, err := validCert(domain, [][]byte{newCert}, newKey) + if err != nil { + t.Fatal(err) + } + newTLSCert := &tls.Certificate{PrivateKey: newKey, Certificate: [][]byte{newCert}, Leaf: newLeaf} + if err := man.cachePut(context.Background(), domain, newTLSCert); err != nil { + t.Fatal(err) + } + + // set internal state to an almost expired cert + oldCert, err := dateDummyCert(key.Public(), now.Add(-2*time.Hour), now.Add(time.Minute), domain) + if err != nil { + t.Fatal(err) + } + oldLeaf, err := validCert(domain, [][]byte{oldCert}, key) + if err != nil { + t.Fatal(err) + } + man.stateMu.Lock() + if man.state == nil { + man.state = make(map[string]*certState) + } + s := &certState{ + key: key, + cert: [][]byte{oldCert}, + leaf: oldLeaf, + } + man.state[domain] = s + man.stateMu.Unlock() + + // veriy the renewal accepted the newer cached cert + defer func() { + testDidRenewLoop = func(next time.Duration, err error) {} + }() + done := make(chan struct{}) + testDidRenewLoop = func(next time.Duration, err error) { + defer close(done) + if err != nil { + t.Errorf("testDidRenewLoop: %v", err) + } + // Next should be about 90 days + // Previous expiration was within 1 min. + future := 88 * 24 * time.Hour + if next < future { + t.Errorf("testDidRenewLoop: next = %v; want >= %v", next, future) + } + + // ensure the cached cert was not modified + tlscert, err := man.cacheGet(context.Background(), domain) + if err != nil { + t.Fatalf("man.cacheGet: %v", err) + } + if !tlscert.Leaf.NotAfter.Equal(newLeaf.NotAfter) { + t.Errorf("cache leaf.NotAfter = %v; want == %v", tlscert.Leaf.NotAfter, newLeaf.NotAfter) + } + + // verify the old cert is also replaced in memory + man.stateMu.Lock() + defer man.stateMu.Unlock() + s := man.state[domain] + if s == nil { + t.Fatalf("m.state[%q] is nil", domain) + } + stateKey := s.key.Public().(*ecdsa.PublicKey) + if stateKey.X.Cmp(newKey.X) != 0 || stateKey.Y.Cmp(newKey.Y) != 0 { + t.Fatalf("state key was not updated from cache x: %v y: %v; want x: %v y: %v", stateKey.X, stateKey.Y, newKey.X, newKey.Y) + } + tlscert, err = s.tlscert() + if err != nil { + t.Fatalf("s.tlscert: %v", err) + } + if !tlscert.Leaf.NotAfter.Equal(newLeaf.NotAfter) { + t.Errorf("state leaf.NotAfter = %v; want == %v", tlscert.Leaf.NotAfter, newLeaf.NotAfter) + } + + // verify the private key is replaced in the renewal state + r := man.renewal[domain] + if r == nil { + t.Fatalf("m.renewal[%q] is nil", domain) + } + renewalKey := r.key.Public().(*ecdsa.PublicKey) + if renewalKey.X.Cmp(newKey.X) != 0 || renewalKey.Y.Cmp(newKey.Y) != 0 { + t.Fatalf("renewal private key was not updated from cache x: %v y: %v; want x: %v y: %v", renewalKey.X, renewalKey.Y, newKey.X, newKey.Y) + } + + } + + // assert the expiring cert is returned from state + hello := &tls.ClientHelloInfo{ServerName: domain} + tlscert, err := man.GetCertificate(hello) + if err != nil { + t.Fatal(err) + } + if !oldLeaf.NotAfter.Equal(tlscert.Leaf.NotAfter) { + t.Errorf("state leaf.NotAfter = %v; want == %v", tlscert.Leaf.NotAfter, oldLeaf.NotAfter) + } + + // trigger renew + go man.renew(domain, s.key, s.leaf.NotAfter) + + // wait for renew loop + select { + case <-time.After(10 * time.Second): + t.Fatal("renew took too long to occur") + case <-done: + // assert the new cert is returned from state after renew + hello := &tls.ClientHelloInfo{ServerName: domain} + tlscert, err := man.GetCertificate(hello) + if err != nil { + t.Fatal(err) + } + if !newTLSCert.Leaf.NotAfter.Equal(tlscert.Leaf.NotAfter) { + t.Errorf("state leaf.NotAfter = %v; want == %v", tlscert.Leaf.NotAfter, newTLSCert.Leaf.NotAfter) + } + } +} diff --git a/vendor/golang.org/x/crypto/ed25519/ed25519.go b/vendor/golang.org/x/crypto/ed25519/ed25519.go index 4f26b49b6..a57771a1e 100644 --- a/vendor/golang.org/x/crypto/ed25519/ed25519.go +++ b/vendor/golang.org/x/crypto/ed25519/ed25519.go @@ -171,9 +171,16 @@ func Verify(publicKey PublicKey, message, sig []byte) bool { edwards25519.ScReduce(&hReduced, &digest) var R edwards25519.ProjectiveGroupElement - var b [32]byte - copy(b[:], sig[32:]) - edwards25519.GeDoubleScalarMultVartime(&R, &hReduced, &A, &b) + var s [32]byte + copy(s[:], sig[32:]) + + // https://tools.ietf.org/html/rfc8032#section-5.1.7 requires that s be in + // the range [0, order) in order to prevent signature malleability. + if !edwards25519.ScMinimal(&s) { + return false + } + + edwards25519.GeDoubleScalarMultVartime(&R, &hReduced, &A, &s) var checkR [32]byte R.ToBytes(&checkR) diff --git a/vendor/golang.org/x/crypto/ed25519/ed25519_test.go b/vendor/golang.org/x/crypto/ed25519/ed25519_test.go index e272f8a55..5f946e996 100644 --- a/vendor/golang.org/x/crypto/ed25519/ed25519_test.go +++ b/vendor/golang.org/x/crypto/ed25519/ed25519_test.go @@ -146,6 +146,30 @@ func TestGolden(t *testing.T) { } } +func TestMalleability(t *testing.T) { + // https://tools.ietf.org/html/rfc8032#section-5.1.7 adds an additional test + // that s be in [0, order). This prevents someone from adding a multiple of + // order to s and obtaining a second valid signature for the same message. + msg := []byte{0x54, 0x65, 0x73, 0x74} + sig := []byte{ + 0x7c, 0x38, 0xe0, 0x26, 0xf2, 0x9e, 0x14, 0xaa, 0xbd, 0x05, 0x9a, + 0x0f, 0x2d, 0xb8, 0xb0, 0xcd, 0x78, 0x30, 0x40, 0x60, 0x9a, 0x8b, + 0xe6, 0x84, 0xdb, 0x12, 0xf8, 0x2a, 0x27, 0x77, 0x4a, 0xb0, 0x67, + 0x65, 0x4b, 0xce, 0x38, 0x32, 0xc2, 0xd7, 0x6f, 0x8f, 0x6f, 0x5d, + 0xaf, 0xc0, 0x8d, 0x93, 0x39, 0xd4, 0xee, 0xf6, 0x76, 0x57, 0x33, + 0x36, 0xa5, 0xc5, 0x1e, 0xb6, 0xf9, 0x46, 0xb3, 0x1d, + } + publicKey := []byte{ + 0x7d, 0x4d, 0x0e, 0x7f, 0x61, 0x53, 0xa6, 0x9b, 0x62, 0x42, 0xb5, + 0x22, 0xab, 0xbe, 0xe6, 0x85, 0xfd, 0xa4, 0x42, 0x0f, 0x88, 0x34, + 0xb1, 0x08, 0xc3, 0xbd, 0xae, 0x36, 0x9e, 0xf5, 0x49, 0xfa, + } + + if Verify(publicKey, msg, sig) { + t.Fatal("non-canonical signature accepted") + } +} + func BenchmarkKeyGeneration(b *testing.B) { var zero zeroReader for i := 0; i < b.N; i++ { diff --git a/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go b/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go index 5f8b99478..fd03c252a 100644 --- a/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go +++ b/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go @@ -4,6 +4,8 @@ package edwards25519 +import "encoding/binary" + // This code is a port of the public domain, “ref10” implementation of ed25519 // from SUPERCOP. @@ -1769,3 +1771,23 @@ func ScReduce(out *[32]byte, s *[64]byte) { out[30] = byte(s11 >> 9) out[31] = byte(s11 >> 17) } + +// order is the order of Curve25519 in little-endian form. +var order = [4]uint64{0x5812631a5cf5d3ed, 0x14def9dea2f79cd6, 0, 0x1000000000000000} + +// ScMinimal returns true if the given scalar is less than the order of the +// curve. +func ScMinimal(scalar *[32]byte) bool { + for i := 3; ; i-- { + v := binary.LittleEndian.Uint64(scalar[i*8:]) + if v > order[i] { + return false + } else if v < order[i] { + break + } else if i == 0 { + return false + } + } + + return true +} diff --git a/vendor/golang.org/x/crypto/nacl/sign/sign.go b/vendor/golang.org/x/crypto/nacl/sign/sign.go new file mode 100644 index 000000000..a9ac0a771 --- /dev/null +++ b/vendor/golang.org/x/crypto/nacl/sign/sign.go @@ -0,0 +1,83 @@ +// 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 sign signs small messages using public-key cryptography. +// +// Sign uses Ed25519 to sign messages. The length of messages is not hidden. +// Messages should be small because: +// 1. The whole message needs to be held in memory to be processed. +// 2. Using large messages pressures implementations on small machines to process +// plaintext without verifying the signature. This is very dangerous, and this API +// discourages it, but a protocol that uses excessive message sizes might present +// some implementations with no other choice. +// 3. Performance may be improved by working with messages that fit into data caches. +// Thus large amounts of data should be chunked so that each message is small. +// +// This package is not interoperable with the current release of NaCl +// (https://nacl.cr.yp.to/sign.html), which does not support Ed25519 yet. However, +// it is compatible with the NaCl fork libsodium (https://www.libsodium.org), as well +// as TweetNaCl (https://tweetnacl.cr.yp.to/). +package sign + +import ( + "io" + + "golang.org/x/crypto/ed25519" +) + +// Overhead is the number of bytes of overhead when signing a message. +const Overhead = 64 + +// GenerateKey generates a new public/private key pair suitable for use with +// Sign and Open. +func GenerateKey(rand io.Reader) (publicKey *[32]byte, privateKey *[64]byte, err error) { + pub, priv, err := ed25519.GenerateKey(rand) + if err != nil { + return nil, nil, err + } + publicKey, privateKey = new([32]byte), new([64]byte) + copy((*publicKey)[:], pub) + copy((*privateKey)[:], priv) + return publicKey, privateKey, nil +} + +// Sign appends a signed copy of message to out, which will be Overhead bytes +// longer than the original and must not overlap it. +func Sign(out, message []byte, privateKey *[64]byte) []byte { + sig := ed25519.Sign(ed25519.PrivateKey((*privateKey)[:]), message) + ret, out := sliceForAppend(out, Overhead+len(message)) + copy(out, sig) + copy(out[Overhead:], message) + return ret +} + +// Open verifies a signed message produced by Sign and appends the message to +// out, which must not overlap the signed message. The output will be Overhead +// bytes smaller than the signed message. +func Open(out, signedMessage []byte, publicKey *[32]byte) ([]byte, bool) { + if len(signedMessage) < Overhead { + return nil, false + } + if !ed25519.Verify(ed25519.PublicKey((*publicKey)[:]), signedMessage[Overhead:], signedMessage[:Overhead]) { + return nil, false + } + ret, out := sliceForAppend(out, len(signedMessage)-Overhead) + copy(out, signedMessage[Overhead:]) + return ret, true +} + +// sliceForAppend takes a slice and a requested number of bytes. It returns a +// slice with the contents of the given slice followed by that many bytes and a +// second slice that aliases into it and contains only the extra bytes. If the +// original slice has sufficient capacity then no allocation is performed. +func sliceForAppend(in []byte, n int) (head, tail []byte) { + if total := len(in) + n; cap(in) >= total { + head = in[:total] + } else { + head = make([]byte, total) + copy(head, in) + } + tail = head[len(in):] + return +} diff --git a/vendor/golang.org/x/crypto/nacl/sign/sign_test.go b/vendor/golang.org/x/crypto/nacl/sign/sign_test.go new file mode 100644 index 000000000..0a6439a62 --- /dev/null +++ b/vendor/golang.org/x/crypto/nacl/sign/sign_test.go @@ -0,0 +1,74 @@ +// 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 sign + +import ( + "bytes" + "crypto/rand" + "encoding/hex" + "testing" +) + +var testSignedMessage, _ = hex.DecodeString("26a0a47f733d02ddb74589b6cbd6f64a7dab1947db79395a1a9e00e4c902c0f185b119897b89b248d16bab4ea781b5a3798d25c2984aec833dddab57e0891e0d68656c6c6f20776f726c64") +var testMessage = testSignedMessage[Overhead:] +var testPublicKey [32]byte +var testPrivateKey = [64]byte{ + 0x98, 0x3c, 0x6a, 0xa6, 0x21, 0xcc, 0xbb, 0xb2, 0xa7, 0xe8, 0x97, 0x94, 0xde, 0x5f, 0xf8, 0x11, + 0x8a, 0xf3, 0x33, 0x1a, 0x03, 0x5c, 0x43, 0x99, 0x03, 0x13, 0x2d, 0xd7, 0xb4, 0xc4, 0x8b, 0xb0, + 0xf6, 0x33, 0x20, 0xa3, 0x34, 0x8b, 0x7b, 0xe2, 0xfe, 0xb4, 0xe7, 0x3a, 0x54, 0x08, 0x2d, 0xd7, + 0x0c, 0xb7, 0xc0, 0xe3, 0xbf, 0x62, 0x6c, 0x55, 0xf0, 0x33, 0x28, 0x52, 0xf8, 0x48, 0x7d, 0xfd, +} + +func init() { + copy(testPublicKey[:], testPrivateKey[32:]) +} + +func TestSign(t *testing.T) { + signedMessage := Sign(nil, testMessage, &testPrivateKey) + if !bytes.Equal(signedMessage, testSignedMessage) { + t.Fatalf("signed message did not match, got\n%x\n, expected\n%x", signedMessage, testSignedMessage) + } +} + +func TestOpen(t *testing.T) { + message, ok := Open(nil, testSignedMessage, &testPublicKey) + if !ok { + t.Fatalf("valid signed message not successfully verified") + } + if !bytes.Equal(message, testMessage) { + t.Fatalf("message did not match, got\n%x\n, expected\n%x", message, testMessage) + } + message, ok = Open(nil, testSignedMessage[1:], &testPublicKey) + if ok { + t.Fatalf("invalid signed message successfully verified") + } + + badMessage := make([]byte, len(testSignedMessage)) + copy(badMessage, testSignedMessage) + badMessage[5] ^= 1 + if _, ok := Open(nil, badMessage, &testPublicKey); ok { + t.Fatalf("Open succeeded with a corrupt message") + } + + var badPublicKey [32]byte + copy(badPublicKey[:], testPublicKey[:]) + badPublicKey[5] ^= 1 + if _, ok := Open(nil, testSignedMessage, &badPublicKey); ok { + t.Fatalf("Open succeeded with a corrupt public key") + } +} + +func TestGenerateSignOpen(t *testing.T) { + publicKey, privateKey, _ := GenerateKey(rand.Reader) + signedMessage := Sign(nil, testMessage, privateKey) + message, ok := Open(nil, signedMessage, publicKey) + if !ok { + t.Fatalf("failed to verify signed message") + } + + if !bytes.Equal(message, testMessage) { + t.Fatalf("verified message does not match signed messge, got\n%x\n, expected\n%x", message, testMessage) + } +} diff --git a/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go b/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go index 266840d05..02b372cf3 100644 --- a/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go +++ b/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go @@ -42,12 +42,18 @@ func (e *EncryptedKey) parse(r io.Reader) (err error) { switch e.Algo { case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly: e.encryptedMPI1.bytes, e.encryptedMPI1.bitLength, err = readMPI(r) + if err != nil { + return + } case PubKeyAlgoElGamal: e.encryptedMPI1.bytes, e.encryptedMPI1.bitLength, err = readMPI(r) if err != nil { return } e.encryptedMPI2.bytes, e.encryptedMPI2.bitLength, err = readMPI(r) + if err != nil { + return + } } _, err = consumeAll(r) return @@ -72,7 +78,8 @@ func (e *EncryptedKey) Decrypt(priv *PrivateKey, config *Config) error { // padding oracle attacks. switch priv.PubKeyAlgo { case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly: - b, err = rsa.DecryptPKCS1v15(config.Random(), priv.PrivateKey.(*rsa.PrivateKey), e.encryptedMPI1.bytes) + k := priv.PrivateKey.(*rsa.PrivateKey) + b, err = rsa.DecryptPKCS1v15(config.Random(), k, padToKeySize(&k.PublicKey, e.encryptedMPI1.bytes)) case PubKeyAlgoElGamal: c1 := new(big.Int).SetBytes(e.encryptedMPI1.bytes) c2 := new(big.Int).SetBytes(e.encryptedMPI2.bytes) diff --git a/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key_test.go b/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key_test.go index fee14cf3c..f2fcf4d35 100644 --- a/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key_test.go +++ b/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key_test.go @@ -39,39 +39,44 @@ var encryptedKeyPriv = &PrivateKey{ } func TestDecryptingEncryptedKey(t *testing.T) { - const encryptedKeyHex = "c18c032a67d68660df41c70104005789d0de26b6a50c985a02a13131ca829c413a35d0e6fa8d6842599252162808ac7439c72151c8c6183e76923fe3299301414d0c25a2f06a2257db3839e7df0ec964773f6e4c4ac7ff3b48c444237166dd46ba8ff443a5410dc670cb486672fdbe7c9dfafb75b4fea83af3a204fe2a7dfa86bd20122b4f3d2646cbeecb8f7be8" - const expectedKeyHex = "d930363f7e0308c333b9618617ea728963d8df993665ae7be1092d4926fd864b" + for i, encryptedKeyHex := range []string{ + "c18c032a67d68660df41c70104005789d0de26b6a50c985a02a13131ca829c413a35d0e6fa8d6842599252162808ac7439c72151c8c6183e76923fe3299301414d0c25a2f06a2257db3839e7df0ec964773f6e4c4ac7ff3b48c444237166dd46ba8ff443a5410dc670cb486672fdbe7c9dfafb75b4fea83af3a204fe2a7dfa86bd20122b4f3d2646cbeecb8f7be8", + // MPI can be shorter than the length of the key. + "c18b032a67d68660df41c70103f8e520c52ae9807183c669ce26e772e482dc5d8cf60e6f59316e145be14d2e5221ee69550db1d5618a8cb002a719f1f0b9345bde21536d410ec90ba86cac37748dec7933eb7f9873873b2d61d3321d1cd44535014f6df58f7bc0c7afb5edc38e1a974428997d2f747f9a173bea9ca53079b409517d332df62d805564cffc9be6", + } { + const expectedKeyHex = "d930363f7e0308c333b9618617ea728963d8df993665ae7be1092d4926fd864b" - p, err := Read(readerFromHex(encryptedKeyHex)) - if err != nil { - t.Errorf("error from Read: %s", err) - return - } - ek, ok := p.(*EncryptedKey) - if !ok { - t.Errorf("didn't parse an EncryptedKey, got %#v", p) - return - } + p, err := Read(readerFromHex(encryptedKeyHex)) + if err != nil { + t.Errorf("#%d: error from Read: %s", i, err) + return + } + ek, ok := p.(*EncryptedKey) + if !ok { + t.Errorf("#%d: didn't parse an EncryptedKey, got %#v", i, p) + return + } - if ek.KeyId != 0x2a67d68660df41c7 || ek.Algo != PubKeyAlgoRSA { - t.Errorf("unexpected EncryptedKey contents: %#v", ek) - return - } + if ek.KeyId != 0x2a67d68660df41c7 || ek.Algo != PubKeyAlgoRSA { + t.Errorf("#%d: unexpected EncryptedKey contents: %#v", i, ek) + return + } - err = ek.Decrypt(encryptedKeyPriv, nil) - if err != nil { - t.Errorf("error from Decrypt: %s", err) - return - } + err = ek.Decrypt(encryptedKeyPriv, nil) + if err != nil { + t.Errorf("#%d: error from Decrypt: %s", i, err) + return + } - if ek.CipherFunc != CipherAES256 { - t.Errorf("unexpected EncryptedKey contents: %#v", ek) - return - } + if ek.CipherFunc != CipherAES256 { + t.Errorf("#%d: unexpected EncryptedKey contents: %#v", i, ek) + return + } - keyHex := fmt.Sprintf("%x", ek.Key) - if keyHex != expectedKeyHex { - t.Errorf("bad key, got %s want %x", keyHex, expectedKeyHex) + keyHex := fmt.Sprintf("%x", ek.Key) + if keyHex != expectedKeyHex { + t.Errorf("#%d: bad key, got %s want %s", i, keyHex, expectedKeyHex) + } } } @@ -121,7 +126,7 @@ func TestEncryptingEncryptedKey(t *testing.T) { keyHex := fmt.Sprintf("%x", ek.Key) if keyHex != expectedKeyHex { - t.Errorf("bad key, got %s want %x", keyHex, expectedKeyHex) + t.Errorf("bad key, got %s want %s", keyHex, expectedKeyHex) } } diff --git a/vendor/golang.org/x/crypto/openpgp/packet/packet.go b/vendor/golang.org/x/crypto/openpgp/packet/packet.go index 3eded93f0..625bb5ac8 100644 --- a/vendor/golang.org/x/crypto/openpgp/packet/packet.go +++ b/vendor/golang.org/x/crypto/openpgp/packet/packet.go @@ -11,10 +11,12 @@ import ( "crypto/aes" "crypto/cipher" "crypto/des" - "golang.org/x/crypto/cast5" - "golang.org/x/crypto/openpgp/errors" + "crypto/rsa" "io" "math/big" + + "golang.org/x/crypto/cast5" + "golang.org/x/crypto/openpgp/errors" ) // readFull is the same as io.ReadFull except that reading zero bytes returns @@ -500,19 +502,17 @@ func readMPI(r io.Reader) (mpi []byte, bitLength uint16, err error) { numBytes := (int(bitLength) + 7) / 8 mpi = make([]byte, numBytes) _, err = readFull(r, mpi) - return -} - -// mpiLength returns the length of the given *big.Int when serialized as an -// MPI. -func mpiLength(n *big.Int) (mpiLengthInBytes int) { - mpiLengthInBytes = 2 /* MPI length */ - mpiLengthInBytes += (n.BitLen() + 7) / 8 + // According to RFC 4880 3.2. we should check that the MPI has no leading + // zeroes (at least when not an encrypted MPI?), but this implementation + // does generate leading zeroes, so we keep accepting them. return } // writeMPI serializes a big integer to w. func writeMPI(w io.Writer, bitLength uint16, mpiBytes []byte) (err error) { + // Note that we can produce leading zeroes, in violation of RFC 4880 3.2. + // Implementations seem to be tolerant of them, and stripping them would + // make it complex to guarantee matching re-serialization. _, err = w.Write([]byte{byte(bitLength >> 8), byte(bitLength)}) if err == nil { _, err = w.Write(mpiBytes) @@ -525,6 +525,18 @@ func writeBig(w io.Writer, i *big.Int) error { return writeMPI(w, uint16(i.BitLen()), i.Bytes()) } +// padToKeySize left-pads a MPI with zeroes to match the length of the +// specified RSA public. +func padToKeySize(pub *rsa.PublicKey, b []byte) []byte { + k := (pub.N.BitLen() + 7) / 8 + if len(b) >= k { + return b + } + bb := make([]byte, k) + copy(bb[len(bb)-len(b):], b) + return bb +} + // CompressionAlgo Represents the different compression algorithms // supported by OpenPGP (except for BZIP2, which is not currently // supported). See Section 9.3 of RFC 4880. diff --git a/vendor/golang.org/x/crypto/openpgp/packet/public_key.go b/vendor/golang.org/x/crypto/openpgp/packet/public_key.go index ead26233d..fcd5f5251 100644 --- a/vendor/golang.org/x/crypto/openpgp/packet/public_key.go +++ b/vendor/golang.org/x/crypto/openpgp/packet/public_key.go @@ -244,7 +244,12 @@ func NewECDSAPublicKey(creationTime time.Time, pub *ecdsa.PublicKey) *PublicKey } pk.ec.p.bytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y) - pk.ec.p.bitLength = uint16(8 * len(pk.ec.p.bytes)) + + // The bit length is 3 (for the 0x04 specifying an uncompressed key) + // plus two field elements (for x and y), which are rounded up to the + // nearest byte. See https://tools.ietf.org/html/rfc6637#section-6 + fieldBytes := (pub.Curve.Params().BitSize + 7) & ^7 + pk.ec.p.bitLength = uint16(3 + fieldBytes + fieldBytes) pk.setFingerPrintAndKeyId() return pk @@ -515,7 +520,7 @@ func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err erro switch pk.PubKeyAlgo { case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: rsaPublicKey, _ := pk.PublicKey.(*rsa.PublicKey) - err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes) + err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, padToKeySize(rsaPublicKey, sig.RSASignature.bytes)) if err != nil { return errors.SignatureError("RSA verification failure") } @@ -566,7 +571,7 @@ func (pk *PublicKey) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (err switch pk.PubKeyAlgo { case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: rsaPublicKey := pk.PublicKey.(*rsa.PublicKey) - if err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes); err != nil { + if err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, padToKeySize(rsaPublicKey, sig.RSASignature.bytes)); err != nil { return errors.SignatureError("RSA verification failure") } return diff --git a/vendor/golang.org/x/crypto/openpgp/packet/public_key_test.go b/vendor/golang.org/x/crypto/openpgp/packet/public_key_test.go index 7ad7d9185..103696ee7 100644 --- a/vendor/golang.org/x/crypto/openpgp/packet/public_key_test.go +++ b/vendor/golang.org/x/crypto/openpgp/packet/public_key_test.go @@ -6,7 +6,10 @@ package packet import ( "bytes" + "crypto/ecdsa" + "crypto/elliptic" "encoding/hex" + "math/big" "testing" "time" ) @@ -186,6 +189,29 @@ func TestEcc384Serialize(t *testing.T) { } } +func TestP256KeyID(t *testing.T) { + // Confirm that key IDs are correctly calculated for ECC keys. + ecdsaPub := &ecdsa.PublicKey{ + Curve: elliptic.P256(), + X: fromHex("81fbbc20eea9e8d1c3ceabb0a8185925b113d1ac42cd5c78403bd83da19235c6"), + Y: fromHex("5ed6db13d91db34507d0129bf88981878d29adbf8fcd1720afdb767bb3fcaaff"), + } + pub := NewECDSAPublicKey(time.Unix(1297309478, 0), ecdsaPub) + + const want = uint64(0xd01055fbcadd268e) + if pub.KeyId != want { + t.Errorf("want key ID: %x, got %x", want, pub.KeyId) + } +} + +func fromHex(hex string) *big.Int { + n, ok := new(big.Int).SetString(hex, 16) + if !ok { + panic("bad hex number: " + hex) + } + return n +} + const rsaFingerprintHex = "5fb74b1d03b1e3cb31bc2f8aa34d7e18c20c31bb" const rsaPkDataHex = "988d044d3c5c10010400b1d13382944bd5aba23a4312968b5095d14f947f600eb478e14a6fcb16b0e0cac764884909c020bc495cfcc39a935387c661507bdb236a0612fb582cac3af9b29cc2c8c70090616c41b662f4da4c1201e195472eb7f4ae1ccbcbf9940fe21d985e379a5563dde5b9a23d35f1cfaa5790da3b79db26f23695107bfaca8e7b5bcd0011010001" diff --git a/vendor/golang.org/x/crypto/sha3/shake.go b/vendor/golang.org/x/crypto/sha3/shake.go index 841f9860f..5a027d2da 100644 --- a/vendor/golang.org/x/crypto/sha3/shake.go +++ b/vendor/golang.org/x/crypto/sha3/shake.go @@ -40,7 +40,7 @@ func (d *state) Clone() ShakeHash { // least 32 bytes of its output are used. func NewShake128() ShakeHash { return &state{rate: 168, dsbyte: 0x1f} } -// NewShake256 creates a new SHAKE128 variable-output-length ShakeHash. +// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash. // Its generic security strength is 256 bits against all attacks if // at least 64 bytes of its output are used. func NewShake256() ShakeHash { return &state{rate: 136, dsbyte: 0x1f} } diff --git a/vendor/golang.org/x/net/CONTRIBUTING.md b/vendor/golang.org/x/net/CONTRIBUTING.md index 88dff59bc..d0485e887 100644 --- a/vendor/golang.org/x/net/CONTRIBUTING.md +++ b/vendor/golang.org/x/net/CONTRIBUTING.md @@ -4,16 +4,15 @@ Go is an open source project. It is the work of hundreds of contributors. We appreciate your help! - ## Filing issues When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions: -1. What version of Go are you using (`go version`)? -2. What operating system and processor architecture are you using? -3. What did you do? -4. What did you expect to see? -5. What did you see instead? +1. What version of Go are you using (`go version`)? +2. What operating system and processor architecture are you using? +3. What did you do? +4. What did you expect to see? +5. What did you see instead? General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker. The gophers there will answer or ask you to file an issue if you've tripped over a bug. @@ -23,9 +22,5 @@ The gophers there will answer or ask you to file an issue if you've tripped over Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) before sending patches. -**We do not accept GitHub pull requests** -(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review). - Unless otherwise noted, the Go source files are distributed under the BSD-style license found in the LICENSE file. - diff --git a/vendor/golang.org/x/net/dns/dnsmessage/message.go b/vendor/golang.org/x/net/dns/dnsmessage/message.go index 624f9b69f..d8d3b0342 100644 --- a/vendor/golang.org/x/net/dns/dnsmessage/message.go +++ b/vendor/golang.org/x/net/dns/dnsmessage/message.go @@ -90,6 +90,8 @@ var ( errTooManyAuthorities = errors.New("too many Authorities to pack (>65535)") errTooManyAdditionals = errors.New("too many Additionals to pack (>65535)") errNonCanonicalName = errors.New("name is not in canonical format (it must end with a .)") + errStringTooLong = errors.New("character string exceeds maximum length (255)") + errCompressedSRV = errors.New("compressed name in SRV resource data") ) // Internal constants. @@ -218,6 +220,7 @@ func (h *header) count(sec section) uint16 { return 0 } +// pack appends the wire format of the header to msg. func (h *header) pack(msg []byte) []byte { msg = packUint16(msg, h.id) msg = packUint16(msg, h.bits) @@ -280,6 +283,7 @@ type ResourceBody interface { realType() Type } +// pack appends the wire format of the Resource to msg. func (r *Resource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { if r.Body == nil { return msg, errNilResouceBody @@ -1311,9 +1315,10 @@ type ResourceHeader struct { Length uint16 } -// pack packs all of the fields in a ResourceHeader except for the length. The -// length bytes are returned as a slice so they can be filled in after the rest -// of the Resource has been packed. +// pack appends the wire format of the ResourceHeader to oldMsg. +// +// The bytes where length was packed are returned as a slice so they can be +// updated after the rest of the Resource has been packed. func (h *ResourceHeader) pack(oldMsg []byte, compression map[string]int, compressionOff int) (msg []byte, length []byte, err error) { msg = oldMsg if msg, err = h.Name.pack(msg, compression, compressionOff); err != nil { @@ -1385,6 +1390,7 @@ func skipResource(msg []byte, off int) (int, error) { return newOff, nil } +// packUint16 appends the wire format of field to msg. func packUint16(msg []byte, field uint16) []byte { return append(msg, byte(field>>8), byte(field)) } @@ -1403,6 +1409,7 @@ func skipUint16(msg []byte, off int) (int, error) { return off + uint16Len, nil } +// packType appends the wire format of field to msg. func packType(msg []byte, field Type) []byte { return packUint16(msg, uint16(field)) } @@ -1416,6 +1423,7 @@ func skipType(msg []byte, off int) (int, error) { return skipUint16(msg, off) } +// packClass appends the wire format of field to msg. func packClass(msg []byte, field Class) []byte { return packUint16(msg, uint16(field)) } @@ -1429,6 +1437,7 @@ func skipClass(msg []byte, off int) (int, error) { return skipUint16(msg, off) } +// packUint32 appends the wire format of field to msg. func packUint32(msg []byte, field uint32) []byte { return append( msg, @@ -1454,17 +1463,16 @@ func skipUint32(msg []byte, off int) (int, error) { return off + uint32Len, nil } -func packText(msg []byte, field string) []byte { - for len(field) > 0 { - l := len(field) - if l > 255 { - l = 255 - } - msg = append(msg, byte(l)) - msg = append(msg, field[:l]...) - field = field[l:] +// packText appends the wire format of field to msg. +func packText(msg []byte, field string) ([]byte, error) { + l := len(field) + if l > 255 { + return nil, errStringTooLong } - return msg + msg = append(msg, byte(l)) + msg = append(msg, field...) + + return msg, nil } func unpackText(msg []byte, off int) (string, int, error) { @@ -1490,6 +1498,7 @@ func skipText(msg []byte, off int) (int, error) { return endOff, nil } +// packBytes appends the wire format of field to msg. func packBytes(msg []byte, field []byte) []byte { return append(msg, field...) } @@ -1534,7 +1543,7 @@ func (n Name) String() string { return string(n.Data[:n.Length]) } -// pack packs a domain name. +// pack appends the wire format of the Name to msg. // // Domain names are a sequence of counted strings split at the dots. They end // with a zero-length string. Compression can be used to reuse domain suffixes. @@ -1602,6 +1611,10 @@ func (n *Name) pack(msg []byte, compression map[string]int, compressionOff int) // unpack unpacks a domain name. func (n *Name) unpack(msg []byte, off int) (int, error) { + return n.unpackCompressed(msg, off, true /* allowCompression */) +} + +func (n *Name) unpackCompressed(msg []byte, off int, allowCompression bool) (int, error) { // currOff is the current working offset. currOff := off @@ -1637,6 +1650,9 @@ Loop: name = append(name, '.') currOff = endOff case 0xC0: // Pointer + if !allowCompression { + return off, errCompressedSRV + } if currOff >= len(msg) { return off, errInvalidPtr } @@ -1716,6 +1732,7 @@ type Question struct { Class Class } +// pack appends the wire format of the Question to msg. func (q *Question) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { msg, err := q.Name.pack(msg, compression, compressionOff) if err != nil { @@ -1796,6 +1813,7 @@ func (r *CNAMEResource) realType() Type { return TypeCNAME } +// pack appends the wire format of the CNAMEResource to msg. func (r *CNAMEResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { return r.CNAME.pack(msg, compression, compressionOff) } @@ -1818,6 +1836,7 @@ func (r *MXResource) realType() Type { return TypeMX } +// pack appends the wire format of the MXResource to msg. func (r *MXResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { oldMsg := msg msg = packUint16(msg, r.Pref) @@ -1849,6 +1868,7 @@ func (r *NSResource) realType() Type { return TypeNS } +// pack appends the wire format of the NSResource to msg. func (r *NSResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { return r.NS.pack(msg, compression, compressionOff) } @@ -1870,6 +1890,7 @@ func (r *PTRResource) realType() Type { return TypePTR } +// pack appends the wire format of the PTRResource to msg. func (r *PTRResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { return r.PTR.pack(msg, compression, compressionOff) } @@ -1901,6 +1922,7 @@ func (r *SOAResource) realType() Type { return TypeSOA } +// pack appends the wire format of the SOAResource to msg. func (r *SOAResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { oldMsg := msg msg, err := r.NS.pack(msg, compression, compressionOff) @@ -1953,19 +1975,28 @@ func unpackSOAResource(msg []byte, off int) (SOAResource, error) { // A TXTResource is a TXT Resource record. type TXTResource struct { - Txt string // Not a domain name. + TXT []string } func (r *TXTResource) realType() Type { return TypeTXT } +// pack appends the wire format of the TXTResource to msg. func (r *TXTResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { - return packText(msg, r.Txt), nil + oldMsg := msg + for _, s := range r.TXT { + var err error + msg, err = packText(msg, s) + if err != nil { + return oldMsg, err + } + } + return msg, nil } func unpackTXTResource(msg []byte, off int, length uint16) (TXTResource, error) { - var txt string + txts := make([]string, 0, 1) for n := uint16(0); n < length; { var t string var err error @@ -1977,9 +2008,9 @@ func unpackTXTResource(msg []byte, off int, length uint16) (TXTResource, error) return TXTResource{}, errCalcLen } n += uint16(len(t)) + 1 - txt += t + txts = append(txts, t) } - return TXTResource{txt}, nil + return TXTResource{txts}, nil } // An SRVResource is an SRV Resource record. @@ -1994,6 +2025,7 @@ func (r *SRVResource) realType() Type { return TypeSRV } +// pack appends the wire format of the SRVResource to msg. func (r *SRVResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { oldMsg := msg msg = packUint16(msg, r.Priority) @@ -2020,7 +2052,7 @@ func unpackSRVResource(msg []byte, off int) (SRVResource, error) { return SRVResource{}, &nestedError{"Port", err} } var target Name - if _, err := target.unpack(msg, off); err != nil { + if _, err := target.unpackCompressed(msg, off, false /* allowCompression */); err != nil { return SRVResource{}, &nestedError{"Target", err} } return SRVResource{priority, weight, port, target}, nil @@ -2035,6 +2067,7 @@ func (r *AResource) realType() Type { return TypeA } +// pack appends the wire format of the AResource to msg. func (r *AResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { return packBytes(msg, r.A[:]), nil } @@ -2056,6 +2089,7 @@ func (r *AAAAResource) realType() Type { return TypeAAAA } +// pack appends the wire format of the AAAAResource to msg. func (r *AAAAResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) { return packBytes(msg, r.AAAA[:]), nil } diff --git a/vendor/golang.org/x/net/dns/dnsmessage/message_test.go b/vendor/golang.org/x/net/dns/dnsmessage/message_test.go index d4eca26f1..052897f3c 100644 --- a/vendor/golang.org/x/net/dns/dnsmessage/message_test.go +++ b/vendor/golang.org/x/net/dns/dnsmessage/message_test.go @@ -8,6 +8,7 @@ import ( "bytes" "fmt" "reflect" + "strings" "testing" ) @@ -157,6 +158,28 @@ func TestNamePackUnpack(t *testing.T) { } } +func TestIncompressibleName(t *testing.T) { + name := mustNewName("example.com.") + compression := map[string]int{} + buf, err := name.pack(make([]byte, 0, 100), compression, 0) + if err != nil { + t.Fatal("First packing failed:", err) + } + buf, err = name.pack(buf, compression, 0) + if err != nil { + t.Fatal("Second packing failed:", err) + } + var n1 Name + off, err := n1.unpackCompressed(buf, 0, false /* allowCompression */) + if err != nil { + t.Fatal("Unpacking incompressible name without pointers failed:", err) + } + var n2 Name + if _, err := n2.unpackCompressed(buf, off, false /* allowCompression */); err != errCompressedSRV { + t.Errorf("Unpacking compressed incompressible name with pointers: got err = %v, want = %v", err, errCompressedSRV) + } +} + func checkErrorPrefix(err error, prefix string) bool { e, ok := err.(*nestedError) return ok && e.s == prefix @@ -444,7 +467,15 @@ func TestVeryLongTxt(t *testing.T) { Type: TypeTXT, Class: ClassINET, }, - &TXTResource{loremIpsum}, + &TXTResource{[]string{ + "", + "", + "foo bar", + "", + "www.example.com", + "www.example.com.", + strings.Repeat(".", 255), + }}, } buf, err := want.pack(make([]byte, 0, 8000), map[string]int{}, 0) if err != nil { @@ -468,6 +499,13 @@ func TestVeryLongTxt(t *testing.T) { } } +func TestTooLongTxt(t *testing.T) { + rb := TXTResource{[]string{strings.Repeat(".", 256)}} + if _, err := rb.pack(make([]byte, 0, 8000), map[string]int{}, 0); err != errStringTooLong { + t.Errorf("Packing TXTRecord with 256 character string: got err = %v, want = %v", err, errStringTooLong) + } +} + func TestStartAppends(t *testing.T) { buf := make([]byte, 2, 514) wantBuf := []byte{4, 44} @@ -1084,7 +1122,7 @@ func largeTestMsg() Message { Type: TypeTXT, Class: ClassINET, }, - &TXTResource{"So Long, and Thanks for All the Fish"}, + &TXTResource{[]string{"So Long, and Thanks for All the Fish"}}, }, { ResourceHeader{ @@ -1092,139 +1130,8 @@ func largeTestMsg() Message { Type: TypeTXT, Class: ClassINET, }, - &TXTResource{"Hamster Huey and the Gooey Kablooie"}, + &TXTResource{[]string{"Hamster Huey and the Gooey Kablooie"}}, }, }, } } - -const loremIpsum = ` -Lorem ipsum dolor sit amet, nec enim antiopam id, an ullum choro -nonumes qui, pro eu debet honestatis mediocritatem. No alia enim eos, -magna signiferumque ex vis. Mei no aperiri dissentias, cu vel quas -regione. Malorum quaeque vim ut, eum cu semper aliquid invidunt, ei -nam ipsum assentior. - -Nostrum appellantur usu no, vis ex probatus adipiscing. Cu usu illum -facilis eleifend. Iusto conceptam complectitur vim id. Tale omnesque -no usu, ei oblique sadipscing vim. At nullam voluptua usu, mei laudem -reformidans et. Qui ei eros porro reformidans, ius suas veritus -torquatos ex. Mea te facer alterum consequat. - -Soleat torquatos democritum sed et, no mea congue appareat, facer -aliquam nec in. Has te ipsum tritani. At justo dicta option nec, movet -phaedrum ad nam. Ea detracto verterem liberavisse has, delectus -suscipiantur in mei. Ex nam meliore complectitur. Ut nam omnis -honestatis quaerendum, ea mea nihil affert detracto, ad vix rebum -mollis. - -Ut epicurei praesent neglegentur pri, prima fuisset intellegebat ad -vim. An habemus comprehensam usu, at enim dignissim pro. Eam reque -vivendum adipisci ea. Vel ne odio choro minimum. Sea admodum -dissentiet ex. Mundi tamquam evertitur ius cu. Homero postea iisque ut -pro, vel ne saepe senserit consetetur. - -Nulla utamur facilisis ius ea, in viderer diceret pertinax eum. Mei no -enim quodsi facilisi, ex sed aeterno appareat mediocritatem, eum -sententiae deterruisset ut. At suas timeam euismod cum, offendit -appareat interpretaris ne vix. Vel ea civibus albucius, ex vim quidam -accusata intellegebat, noluisse instructior sea id. Nec te nonumes -habemus appellantur, quis dignissim vituperata eu nam. - -At vix apeirian patrioque vituperatoribus, an usu agam assum. Debet -iisque an mea. Per eu dicant ponderum accommodare. Pri alienum -placerat senserit an, ne eum ferri abhorreant vituperatoribus. Ut mea -eligendi disputationi. Ius no tation everti impedit, ei magna quidam -mediocritatem pri. - -Legendos perpetua iracundia ne usu, no ius ullum epicurei intellegam, -ad modus epicuri lucilius eam. In unum quaerendum usu. Ne diam paulo -has, ea veri virtute sed. Alia honestatis conclusionemque mea eu, ut -iudico albucius his. - -Usu essent probatus eu, sed omnis dolor delicatissimi ex. No qui augue -dissentias dissentiet. Laudem recteque no usu, vel an velit noluisse, -an sed utinam eirmod appetere. Ne mea fuisset inimicus ocurreret. At -vis dicant abhorreant, utinam forensibus nec ne, mei te docendi -consequat. Brute inermis persecuti cum id. Ut ipsum munere propriae -usu, dicit graeco disputando id has. - -Eros dolore quaerendum nam ei. Timeam ornatus inciderint pro id. Nec -torquatos sadipscing ei, ancillae molestie per in. Malis principes duo -ea, usu liber postulant ei. - -Graece timeam voluptatibus eu eam. Alia probatus quo no, ea scripta -feugiat duo. Congue option meliore ex qui, noster invenire appellantur -ea vel. Eu exerci legendos vel. Consetetur repudiandae vim ut. Vix an -probo minimum, et nam illud falli tempor. - -Cum dico signiferumque eu. Sed ut regione maiorum, id veritus insolens -tacimates vix. Eu mel sint tamquam lucilius, duo no oporteat -tacimates. Atqui augue concludaturque vix ei, id mel utroque menandri. - -Ad oratio blandit aliquando pro. Vis et dolorum rationibus -philosophia, ad cum nulla molestie. Hinc fuisset adversarium eum et, -ne qui nisl verear saperet, vel te quaestio forensibus. Per odio -option delenit an. Alii placerat has no, in pri nihil platonem -cotidieque. Est ut elit copiosae scaevola, debet tollit maluisset sea -an. - -Te sea hinc debet pericula, liber ridens fabulas cu sed, quem mutat -accusam mea et. Elitr labitur albucius et pri, an labore feugait mel. -Velit zril melius usu ea. Ad stet putent interpretaris qui. Mel no -error volumus scripserit. In pro paulo iudico, quo ei dolorem -verterem, affert fabellas dissentiet ea vix. - -Vis quot deserunt te. Error aliquid detraxit eu usu, vis alia eruditi -salutatus cu. Est nostrud bonorum an, ei usu alii salutatus. Vel at -nisl primis, eum ex aperiri noluisse reformidans. Ad veri velit -utroque vis, ex equidem detraxit temporibus has. - -Inermis appareat usu ne. Eros placerat periculis mea ad, in dictas -pericula pro. Errem postulant at usu, ea nec amet ornatus mentitum. Ad -mazim graeco eum, vel ex percipit volutpat iudicabit, sit ne delicata -interesset. Mel sapientem prodesset abhorreant et, oblique suscipit -eam id. - -An maluisset disputando mea, vidit mnesarchum pri et. Malis insolens -inciderint no sea. Ea persius maluisset vix, ne vim appellantur -instructior, consul quidam definiebas pri id. Cum integre feugiat -pericula in, ex sed persius similique, mel ne natum dicit percipitur. - -Primis discere ne pri, errem putent definitionem at vis. Ei mel dolore -neglegentur, mei tincidunt percipitur ei. Pro ad simul integre -rationibus. Eu vel alii honestatis definitiones, mea no nonumy -reprehendunt. - -Dicta appareat legendos est cu. Eu vel congue dicunt omittam, no vix -adhuc minimum constituam, quot noluisse id mel. Eu quot sale mutat -duo, ex nisl munere invenire duo. Ne nec ullum utamur. Pro alterum -debitis nostrum no, ut vel aliquid vivendo. - -Aliquip fierent praesent quo ne, id sit audiam recusabo delicatissimi. -Usu postulant incorrupte cu. At pro dicit tibique intellegam, cibo -dolore impedit id eam, et aeque feugait assentior has. Quando sensibus -nec ex. Possit sensibus pri ad, unum mutat periculis cu vix. - -Mundi tibique vix te, duo simul partiendo qualisque id, est at vidit -sonet tempor. No per solet aeterno deseruisse. Petentium salutandi -definiebas pri cu. Munere vivendum est in. Ei justo congue eligendi -vis, modus offendit omittantur te mel. - -Integre voluptaria in qui, sit habemus tractatos constituam no. Utinam -melius conceptam est ne, quo in minimum apeirian delicata, ut ius -porro recusabo. Dicant expetenda vix no, ludus scripserit sed ex, eu -his modo nostro. Ut etiam sonet his, quodsi inciderint philosophia te -per. Nullam lobortis eu cum, vix an sonet efficiendi repudiandae. Vis -ad idque fabellas intellegebat. - -Eum commodo senserit conclusionemque ex. Sed forensibus sadipscing ut, -mei in facer delicata periculis, sea ne hinc putent cetero. Nec ne -alia corpora invenire, alia prima soleat te cum. Eleifend posidonium -nam at. - -Dolorum indoctum cu quo, ex dolor legendos recteque eam, cu pri zril -discere. Nec civibus officiis dissentiunt ex, est te liber ludus -elaboraret. Cum ea fabellas invenire. Ex vim nostrud eripuit -comprehensam, nam te inermis delectus, saepe inermis senserit. -` diff --git a/vendor/golang.org/x/net/icmp/diag_test.go b/vendor/golang.org/x/net/icmp/diag_test.go new file mode 100644 index 000000000..2ecd465a1 --- /dev/null +++ b/vendor/golang.org/x/net/icmp/diag_test.go @@ -0,0 +1,274 @@ +// Copyright 2014 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 icmp_test + +import ( + "errors" + "fmt" + "net" + "os" + "runtime" + "sync" + "testing" + "time" + + "golang.org/x/net/icmp" + "golang.org/x/net/internal/iana" + "golang.org/x/net/internal/nettest" + "golang.org/x/net/ipv4" + "golang.org/x/net/ipv6" +) + +type diagTest struct { + network, address string + protocol int + m icmp.Message +} + +func TestDiag(t *testing.T) { + if testing.Short() { + t.Skip("avoid external network") + } + + t.Run("Ping/NonPrivileged", func(t *testing.T) { + switch runtime.GOOS { + case "darwin": + case "linux": + t.Log("you may need to adjust the net.ipv4.ping_group_range kernel state") + default: + t.Logf("not supported on %s", runtime.GOOS) + return + } + for i, dt := range []diagTest{ + { + "udp4", "0.0.0.0", iana.ProtocolICMP, + icmp.Message{ + Type: ipv4.ICMPTypeEcho, Code: 0, + Body: &icmp.Echo{ + ID: os.Getpid() & 0xffff, + Data: []byte("HELLO-R-U-THERE"), + }, + }, + }, + + { + "udp6", "::", iana.ProtocolIPv6ICMP, + icmp.Message{ + Type: ipv6.ICMPTypeEchoRequest, Code: 0, + Body: &icmp.Echo{ + ID: os.Getpid() & 0xffff, + Data: []byte("HELLO-R-U-THERE"), + }, + }, + }, + } { + if err := doDiag(dt, i); err != nil { + t.Error(err) + } + } + }) + t.Run("Ping/Privileged", func(t *testing.T) { + if m, ok := nettest.SupportsRawIPSocket(); !ok { + t.Skip(m) + } + for i, dt := range []diagTest{ + { + "ip4:icmp", "0.0.0.0", iana.ProtocolICMP, + icmp.Message{ + Type: ipv4.ICMPTypeEcho, Code: 0, + Body: &icmp.Echo{ + ID: os.Getpid() & 0xffff, + Data: []byte("HELLO-R-U-THERE"), + }, + }, + }, + + { + "ip6:ipv6-icmp", "::", iana.ProtocolIPv6ICMP, + icmp.Message{ + Type: ipv6.ICMPTypeEchoRequest, Code: 0, + Body: &icmp.Echo{ + ID: os.Getpid() & 0xffff, + Data: []byte("HELLO-R-U-THERE"), + }, + }, + }, + } { + if err := doDiag(dt, i); err != nil { + t.Error(err) + } + } + }) + t.Run("Probe/Privileged", func(t *testing.T) { + if m, ok := nettest.SupportsRawIPSocket(); !ok { + t.Skip(m) + } + for i, dt := range []diagTest{ + { + "ip4:icmp", "0.0.0.0", iana.ProtocolICMP, + icmp.Message{ + Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0, + Body: &icmp.ExtendedEchoRequest{ + ID: os.Getpid() & 0xffff, + Local: true, + Extensions: []icmp.Extension{ + &icmp.InterfaceIdent{ + Class: 3, Type: 1, + Name: "doesnotexist", + }, + }, + }, + }, + }, + + { + "ip6:ipv6-icmp", "::", iana.ProtocolIPv6ICMP, + icmp.Message{ + Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0, + Body: &icmp.ExtendedEchoRequest{ + ID: os.Getpid() & 0xffff, + Local: true, + Extensions: []icmp.Extension{ + &icmp.InterfaceIdent{ + Class: 3, Type: 1, + Name: "doesnotexist", + }, + }, + }, + }, + }, + } { + if err := doDiag(dt, i); err != nil { + t.Error(err) + } + } + }) +} + +func doDiag(dt diagTest, seq int) error { + c, err := icmp.ListenPacket(dt.network, dt.address) + if err != nil { + return err + } + defer c.Close() + + dst, err := googleAddr(c, dt.protocol) + if err != nil { + return err + } + + if dt.network != "udp6" && dt.protocol == iana.ProtocolIPv6ICMP { + var f ipv6.ICMPFilter + f.SetAll(true) + f.Accept(ipv6.ICMPTypeDestinationUnreachable) + f.Accept(ipv6.ICMPTypePacketTooBig) + f.Accept(ipv6.ICMPTypeTimeExceeded) + f.Accept(ipv6.ICMPTypeParameterProblem) + f.Accept(ipv6.ICMPTypeEchoReply) + f.Accept(ipv6.ICMPTypeExtendedEchoReply) + if err := c.IPv6PacketConn().SetICMPFilter(&f); err != nil { + return err + } + } + + switch m := dt.m.Body.(type) { + case *icmp.Echo: + m.Seq = 1 << uint(seq) + case *icmp.ExtendedEchoRequest: + m.Seq = 1 << uint(seq) + } + wb, err := dt.m.Marshal(nil) + if err != nil { + return err + } + if n, err := c.WriteTo(wb, dst); err != nil { + return err + } else if n != len(wb) { + return fmt.Errorf("got %v; want %v", n, len(wb)) + } + + rb := make([]byte, 1500) + if err := c.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil { + return err + } + n, peer, err := c.ReadFrom(rb) + if err != nil { + return err + } + rm, err := icmp.ParseMessage(dt.protocol, rb[:n]) + if err != nil { + return err + } + switch { + case dt.m.Type == ipv4.ICMPTypeEcho && rm.Type == ipv4.ICMPTypeEchoReply: + fallthrough + case dt.m.Type == ipv6.ICMPTypeEchoRequest && rm.Type == ipv6.ICMPTypeEchoReply: + fallthrough + case dt.m.Type == ipv4.ICMPTypeExtendedEchoRequest && rm.Type == ipv4.ICMPTypeExtendedEchoReply: + fallthrough + case dt.m.Type == ipv6.ICMPTypeExtendedEchoRequest && rm.Type == ipv6.ICMPTypeExtendedEchoReply: + return nil + default: + return fmt.Errorf("got %+v from %v; want echo reply or extended echo reply", rm, peer) + } +} + +func googleAddr(c *icmp.PacketConn, protocol int) (net.Addr, error) { + host := "ipv4.google.com" + if protocol == iana.ProtocolIPv6ICMP { + host = "ipv6.google.com" + } + ips, err := net.LookupIP(host) + if err != nil { + return nil, err + } + netaddr := func(ip net.IP) (net.Addr, error) { + switch c.LocalAddr().(type) { + case *net.UDPAddr: + return &net.UDPAddr{IP: ip}, nil + case *net.IPAddr: + return &net.IPAddr{IP: ip}, nil + default: + return nil, errors.New("neither UDPAddr nor IPAddr") + } + } + if len(ips) > 0 { + return netaddr(ips[0]) + } + return nil, errors.New("no A or AAAA record") +} + +func TestConcurrentNonPrivilegedListenPacket(t *testing.T) { + if testing.Short() { + t.Skip("avoid external network") + } + switch runtime.GOOS { + case "darwin": + case "linux": + t.Log("you may need to adjust the net.ipv4.ping_group_range kernel state") + default: + t.Skipf("not supported on %s", runtime.GOOS) + } + + network, address := "udp4", "127.0.0.1" + if !nettest.SupportsIPv4() { + network, address = "udp6", "::1" + } + const N = 1000 + var wg sync.WaitGroup + wg.Add(N) + for i := 0; i < N; i++ { + go func() { + defer wg.Done() + c, err := icmp.ListenPacket(network, address) + if err != nil { + t.Error(err) + return + } + c.Close() + }() + } + wg.Wait() +} diff --git a/vendor/golang.org/x/net/icmp/dstunreach.go b/vendor/golang.org/x/net/icmp/dstunreach.go index 75db991df..7464bf7ea 100644 --- a/vendor/golang.org/x/net/icmp/dstunreach.go +++ b/vendor/golang.org/x/net/icmp/dstunreach.go @@ -16,24 +16,24 @@ func (p *DstUnreach) Len(proto int) int { if p == nil { return 0 } - l, _ := multipartMessageBodyDataLen(proto, p.Data, p.Extensions) + l, _ := multipartMessageBodyDataLen(proto, true, p.Data, p.Extensions) return 4 + l } // Marshal implements the Marshal method of MessageBody interface. func (p *DstUnreach) Marshal(proto int) ([]byte, error) { - return marshalMultipartMessageBody(proto, p.Data, p.Extensions) + return marshalMultipartMessageBody(proto, true, p.Data, p.Extensions) } // parseDstUnreach parses b as an ICMP destination unreachable message // body. -func parseDstUnreach(proto int, b []byte) (MessageBody, error) { +func parseDstUnreach(proto int, typ Type, b []byte) (MessageBody, error) { if len(b) < 4 { return nil, errMessageTooShort } p := &DstUnreach{} var err error - p.Data, p.Extensions, err = parseMultipartMessageBody(proto, b) + p.Data, p.Extensions, err = parseMultipartMessageBody(proto, typ, b) if err != nil { return nil, err } diff --git a/vendor/golang.org/x/net/icmp/echo.go b/vendor/golang.org/x/net/icmp/echo.go index e6f15efd7..c611f6516 100644 --- a/vendor/golang.org/x/net/icmp/echo.go +++ b/vendor/golang.org/x/net/icmp/echo.go @@ -31,7 +31,7 @@ func (p *Echo) Marshal(proto int) ([]byte, error) { } // parseEcho parses b as an ICMP echo request or reply message body. -func parseEcho(proto int, b []byte) (MessageBody, error) { +func parseEcho(proto int, _ Type, b []byte) (MessageBody, error) { bodyLen := len(b) if bodyLen < 4 { return nil, errMessageTooShort @@ -43,3 +43,115 @@ func parseEcho(proto int, b []byte) (MessageBody, error) { } return p, nil } + +// An ExtendedEchoRequest represents an ICMP extended echo request +// message body. +type ExtendedEchoRequest struct { + ID int // identifier + Seq int // sequence number + Local bool // must be true when identifying by name or index + Extensions []Extension // extensions +} + +// Len implements the Len method of MessageBody interface. +func (p *ExtendedEchoRequest) Len(proto int) int { + if p == nil { + return 0 + } + l, _ := multipartMessageBodyDataLen(proto, false, nil, p.Extensions) + return 4 + l +} + +// Marshal implements the Marshal method of MessageBody interface. +func (p *ExtendedEchoRequest) Marshal(proto int) ([]byte, error) { + b, err := marshalMultipartMessageBody(proto, false, nil, p.Extensions) + if err != nil { + return nil, err + } + bb := make([]byte, 4) + binary.BigEndian.PutUint16(bb[:2], uint16(p.ID)) + bb[2] = byte(p.Seq) + if p.Local { + bb[3] |= 0x01 + } + bb = append(bb, b...) + return bb, nil +} + +// parseExtendedEchoRequest parses b as an ICMP extended echo request +// message body. +func parseExtendedEchoRequest(proto int, typ Type, b []byte) (MessageBody, error) { + if len(b) < 4+4 { + return nil, errMessageTooShort + } + p := &ExtendedEchoRequest{ID: int(binary.BigEndian.Uint16(b[:2])), Seq: int(b[2])} + if b[3]&0x01 != 0 { + p.Local = true + } + var err error + _, p.Extensions, err = parseMultipartMessageBody(proto, typ, b[4:]) + if err != nil { + return nil, err + } + return p, nil +} + +// An ExtendedEchoReply represents an ICMP extended echo reply message +// body. +type ExtendedEchoReply struct { + ID int // identifier + Seq int // sequence number + State int // 3-bit state working together with Message.Code + Active bool // probed interface is active + IPv4 bool // probed interface runs IPv4 + IPv6 bool // probed interface runs IPv6 +} + +// Len implements the Len method of MessageBody interface. +func (p *ExtendedEchoReply) Len(proto int) int { + if p == nil { + return 0 + } + return 4 +} + +// Marshal implements the Marshal method of MessageBody interface. +func (p *ExtendedEchoReply) Marshal(proto int) ([]byte, error) { + b := make([]byte, 4) + binary.BigEndian.PutUint16(b[:2], uint16(p.ID)) + b[2] = byte(p.Seq) + b[3] = byte(p.State<<5) & 0xe0 + if p.Active { + b[3] |= 0x04 + } + if p.IPv4 { + b[3] |= 0x02 + } + if p.IPv6 { + b[3] |= 0x01 + } + return b, nil +} + +// parseExtendedEchoReply parses b as an ICMP extended echo reply +// message body. +func parseExtendedEchoReply(proto int, _ Type, b []byte) (MessageBody, error) { + if len(b) < 4 { + return nil, errMessageTooShort + } + p := &ExtendedEchoReply{ + ID: int(binary.BigEndian.Uint16(b[:2])), + Seq: int(b[2]), + State: int(b[3]) >> 5, + } + if b[3]&0x04 != 0 { + p.Active = true + } + if b[3]&0x02 != 0 { + p.IPv4 = true + } + if b[3]&0x01 != 0 { + p.IPv6 = true + } + return p, nil +} diff --git a/vendor/golang.org/x/net/icmp/extension.go b/vendor/golang.org/x/net/icmp/extension.go index 402a7514b..200506855 100644 --- a/vendor/golang.org/x/net/icmp/extension.go +++ b/vendor/golang.org/x/net/icmp/extension.go @@ -4,7 +4,12 @@ package icmp -import "encoding/binary" +import ( + "encoding/binary" + + "golang.org/x/net/ipv4" + "golang.org/x/net/ipv6" +) // An Extension represents an ICMP extension. type Extension interface { @@ -38,7 +43,7 @@ func validExtensionHeader(b []byte) bool { // It will return a list of ICMP extensions and an adjusted length // attribute that represents the length of the padded original // datagram field. Otherwise, it returns an error. -func parseExtensions(b []byte, l int) ([]Extension, int, error) { +func parseExtensions(typ Type, b []byte, l int) ([]Extension, int, error) { // Still a lot of non-RFC 4884 compliant implementations are // out there. Set the length attribute l to 128 when it looks // inappropriate for backwards compatibility. @@ -48,20 +53,28 @@ func parseExtensions(b []byte, l int) ([]Extension, int, error) { // header. // // See RFC 4884 for further information. - if 128 > l || l+8 > len(b) { - l = 128 - } - if l+8 > len(b) { - return nil, -1, errNoExtension - } - if !validExtensionHeader(b[l:]) { - if l == 128 { + switch typ { + case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest: + if len(b) < 8 || !validExtensionHeader(b) { return nil, -1, errNoExtension } - l = 128 - if !validExtensionHeader(b[l:]) { + l = 0 + default: + if 128 > l || l+8 > len(b) { + l = 128 + } + if l+8 > len(b) { return nil, -1, errNoExtension } + if !validExtensionHeader(b[l:]) { + if l == 128 { + return nil, -1, errNoExtension + } + l = 128 + if !validExtensionHeader(b[l:]) { + return nil, -1, errNoExtension + } + } } var exts []Extension for b = b[l+4:]; len(b) >= 4; { @@ -82,6 +95,12 @@ func parseExtensions(b []byte, l int) ([]Extension, int, error) { return nil, -1, err } exts = append(exts, ext) + case classInterfaceIdent: + ext, err := parseInterfaceIdent(b[:ol]) + if err != nil { + return nil, -1, err + } + exts = append(exts, ext) } b = b[ol:] } diff --git a/vendor/golang.org/x/net/icmp/extension_test.go b/vendor/golang.org/x/net/icmp/extension_test.go index 0b3f7b9e1..a7669dae0 100644 --- a/vendor/golang.org/x/net/icmp/extension_test.go +++ b/vendor/golang.org/x/net/icmp/extension_test.go @@ -5,253 +5,327 @@ package icmp import ( + "fmt" "net" "reflect" "testing" "golang.org/x/net/internal/iana" + "golang.org/x/net/ipv4" + "golang.org/x/net/ipv6" ) -var marshalAndParseExtensionTests = []struct { - proto int - hdr []byte - obj []byte - exts []Extension -}{ - // MPLS label stack with no label - { - proto: iana.ProtocolICMP, - hdr: []byte{ - 0x20, 0x00, 0x00, 0x00, - }, - obj: []byte{ - 0x00, 0x04, 0x01, 0x01, - }, - exts: []Extension{ - &MPLSLabelStack{ - Class: classMPLSLabelStack, - Type: typeIncomingMPLSLabelStack, - }, - }, - }, - // MPLS label stack with a single label - { - proto: iana.ProtocolIPv6ICMP, - hdr: []byte{ - 0x20, 0x00, 0x00, 0x00, - }, - obj: []byte{ - 0x00, 0x08, 0x01, 0x01, - 0x03, 0xe8, 0xe9, 0xff, - }, - exts: []Extension{ - &MPLSLabelStack{ - Class: classMPLSLabelStack, - Type: typeIncomingMPLSLabelStack, - Labels: []MPLSLabel{ - { - Label: 16014, - TC: 0x4, - S: true, - TTL: 255, - }, - }, - }, - }, - }, - // MPLS label stack with multiple labels - { - proto: iana.ProtocolICMP, - hdr: []byte{ - 0x20, 0x00, 0x00, 0x00, - }, - obj: []byte{ - 0x00, 0x0c, 0x01, 0x01, - 0x03, 0xe8, 0xde, 0xfe, - 0x03, 0xe8, 0xe1, 0xff, - }, - exts: []Extension{ - &MPLSLabelStack{ - Class: classMPLSLabelStack, - Type: typeIncomingMPLSLabelStack, - Labels: []MPLSLabel{ - { - Label: 16013, - TC: 0x7, - S: false, - TTL: 254, - }, - { - Label: 16014, - TC: 0, - S: true, - TTL: 255, - }, - }, - }, - }, - }, - // Interface information with no attribute - { - proto: iana.ProtocolICMP, - hdr: []byte{ - 0x20, 0x00, 0x00, 0x00, - }, - obj: []byte{ - 0x00, 0x04, 0x02, 0x00, - }, - exts: []Extension{ - &InterfaceInfo{ - Class: classInterfaceInfo, - }, - }, - }, - // Interface information with ifIndex and name - { - proto: iana.ProtocolICMP, - hdr: []byte{ - 0x20, 0x00, 0x00, 0x00, - }, - obj: []byte{ - 0x00, 0x10, 0x02, 0x0a, - 0x00, 0x00, 0x00, 0x10, - 0x08, byte('e'), byte('n'), byte('1'), - byte('0'), byte('1'), 0x00, 0x00, - }, - exts: []Extension{ - &InterfaceInfo{ - Class: classInterfaceInfo, - Type: 0x0a, - Interface: &net.Interface{ - Index: 16, - Name: "en101", - }, - }, - }, - }, - // Interface information with ifIndex, IPAddr, name and MTU - { - proto: iana.ProtocolIPv6ICMP, - hdr: []byte{ - 0x20, 0x00, 0x00, 0x00, - }, - obj: []byte{ - 0x00, 0x28, 0x02, 0x0f, - 0x00, 0x00, 0x00, 0x0f, - 0x00, 0x02, 0x00, 0x00, - 0xfe, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, - 0x08, byte('e'), byte('n'), byte('1'), - byte('0'), byte('1'), 0x00, 0x00, - 0x00, 0x00, 0x20, 0x00, - }, - exts: []Extension{ - &InterfaceInfo{ - Class: classInterfaceInfo, - Type: 0x0f, - Interface: &net.Interface{ - Index: 15, - Name: "en101", - MTU: 8192, - }, - Addr: &net.IPAddr{ - IP: net.ParseIP("fe80::1"), - Zone: "en101", - }, - }, - }, - }, -} - func TestMarshalAndParseExtension(t *testing.T) { - for i, tt := range marshalAndParseExtensionTests { - for j, ext := range tt.exts { - var err error - var b []byte - switch ext := ext.(type) { - case *MPLSLabelStack: - b, err = ext.Marshal(tt.proto) - if err != nil { - t.Errorf("#%v/%v: %v", i, j, err) + fn := func(t *testing.T, proto int, typ Type, hdr, obj []byte, te Extension) error { + b, err := te.Marshal(proto) + if err != nil { + return err + } + if !reflect.DeepEqual(b, obj) { + return fmt.Errorf("got %#v; want %#v", b, obj) + } + switch typ { + case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest: + exts, l, err := parseExtensions(typ, append(hdr, obj...), 0) + if err != nil { + return err + } + if l != 0 { + return fmt.Errorf("got %d; want 0", l) + } + if !reflect.DeepEqual(exts, []Extension{te}) { + return fmt.Errorf("got %#v; want %#v", exts[0], te) + } + default: + for i, wire := range []struct { + data []byte // original datagram + inlattr int // length of padded original datagram, a hint + outlattr int // length of padded original datagram, a want + err error + }{ + {nil, 0, -1, errNoExtension}, + {make([]byte, 127), 128, -1, errNoExtension}, + + {make([]byte, 128), 127, -1, errNoExtension}, + {make([]byte, 128), 128, -1, errNoExtension}, + {make([]byte, 128), 129, -1, errNoExtension}, + + {append(make([]byte, 128), append(hdr, obj...)...), 127, 128, nil}, + {append(make([]byte, 128), append(hdr, obj...)...), 128, 128, nil}, + {append(make([]byte, 128), append(hdr, obj...)...), 129, 128, nil}, + + {append(make([]byte, 512), append(hdr, obj...)...), 511, -1, errNoExtension}, + {append(make([]byte, 512), append(hdr, obj...)...), 512, 512, nil}, + {append(make([]byte, 512), append(hdr, obj...)...), 513, -1, errNoExtension}, + } { + exts, l, err := parseExtensions(typ, wire.data, wire.inlattr) + if err != wire.err { + return fmt.Errorf("#%d: got %v; want %v", i, err, wire.err) + } + if wire.err != nil { continue } - case *InterfaceInfo: - b, err = ext.Marshal(tt.proto) - if err != nil { - t.Errorf("#%v/%v: %v", i, j, err) - continue + if l != wire.outlattr { + return fmt.Errorf("#%d: got %d; want %d", i, l, wire.outlattr) + } + if !reflect.DeepEqual(exts, []Extension{te}) { + return fmt.Errorf("#%d: got %#v; want %#v", i, exts[0], te) } } - if !reflect.DeepEqual(b, tt.obj) { - t.Errorf("#%v/%v: got %#v; want %#v", i, j, b, tt.obj) - continue - } - } - - for j, wire := range []struct { - data []byte // original datagram - inlattr int // length of padded original datagram, a hint - outlattr int // length of padded original datagram, a want - err error - }{ - {nil, 0, -1, errNoExtension}, - {make([]byte, 127), 128, -1, errNoExtension}, - - {make([]byte, 128), 127, -1, errNoExtension}, - {make([]byte, 128), 128, -1, errNoExtension}, - {make([]byte, 128), 129, -1, errNoExtension}, - - {append(make([]byte, 128), append(tt.hdr, tt.obj...)...), 127, 128, nil}, - {append(make([]byte, 128), append(tt.hdr, tt.obj...)...), 128, 128, nil}, - {append(make([]byte, 128), append(tt.hdr, tt.obj...)...), 129, 128, nil}, - - {append(make([]byte, 512), append(tt.hdr, tt.obj...)...), 511, -1, errNoExtension}, - {append(make([]byte, 512), append(tt.hdr, tt.obj...)...), 512, 512, nil}, - {append(make([]byte, 512), append(tt.hdr, tt.obj...)...), 513, -1, errNoExtension}, - } { - exts, l, err := parseExtensions(wire.data, wire.inlattr) - if err != wire.err { - t.Errorf("#%v/%v: got %v; want %v", i, j, err, wire.err) - continue - } - if wire.err != nil { - continue - } - if l != wire.outlattr { - t.Errorf("#%v/%v: got %v; want %v", i, j, l, wire.outlattr) - } - if !reflect.DeepEqual(exts, tt.exts) { - for j, ext := range exts { - switch ext := ext.(type) { - case *MPLSLabelStack: - want := tt.exts[j].(*MPLSLabelStack) - t.Errorf("#%v/%v: got %#v; want %#v", i, j, ext, want) - case *InterfaceInfo: - want := tt.exts[j].(*InterfaceInfo) - t.Errorf("#%v/%v: got %#v; want %#v", i, j, ext, want) - } - } - continue - } } + return nil } -} -var parseInterfaceNameTests = []struct { - b []byte - error -}{ - {[]byte{0, 'e', 'n', '0'}, errInvalidExtension}, - {[]byte{4, 'e', 'n', '0'}, nil}, - {[]byte{7, 'e', 'n', '0', 0xff, 0xff, 0xff, 0xff}, errInvalidExtension}, - {[]byte{8, 'e', 'n', '0', 0xff, 0xff, 0xff}, errMessageTooShort}, + t.Run("MPLSLabelStack", func(t *testing.T) { + for _, et := range []struct { + proto int + typ Type + hdr []byte + obj []byte + ext Extension + }{ + // MPLS label stack with no label + { + proto: iana.ProtocolICMP, + typ: ipv4.ICMPTypeDestinationUnreachable, + hdr: []byte{ + 0x20, 0x00, 0x00, 0x00, + }, + obj: []byte{ + 0x00, 0x04, 0x01, 0x01, + }, + ext: &MPLSLabelStack{ + Class: classMPLSLabelStack, + Type: typeIncomingMPLSLabelStack, + }, + }, + // MPLS label stack with a single label + { + proto: iana.ProtocolIPv6ICMP, + typ: ipv6.ICMPTypeDestinationUnreachable, + hdr: []byte{ + 0x20, 0x00, 0x00, 0x00, + }, + obj: []byte{ + 0x00, 0x08, 0x01, 0x01, + 0x03, 0xe8, 0xe9, 0xff, + }, + ext: &MPLSLabelStack{ + Class: classMPLSLabelStack, + Type: typeIncomingMPLSLabelStack, + Labels: []MPLSLabel{ + { + Label: 16014, + TC: 0x4, + S: true, + TTL: 255, + }, + }, + }, + }, + // MPLS label stack with multiple labels + { + proto: iana.ProtocolICMP, + typ: ipv4.ICMPTypeDestinationUnreachable, + hdr: []byte{ + 0x20, 0x00, 0x00, 0x00, + }, + obj: []byte{ + 0x00, 0x0c, 0x01, 0x01, + 0x03, 0xe8, 0xde, 0xfe, + 0x03, 0xe8, 0xe1, 0xff, + }, + ext: &MPLSLabelStack{ + Class: classMPLSLabelStack, + Type: typeIncomingMPLSLabelStack, + Labels: []MPLSLabel{ + { + Label: 16013, + TC: 0x7, + S: false, + TTL: 254, + }, + { + Label: 16014, + TC: 0, + S: true, + TTL: 255, + }, + }, + }, + }, + } { + if err := fn(t, et.proto, et.typ, et.hdr, et.obj, et.ext); err != nil { + t.Error(err) + } + } + }) + t.Run("InterfaceInfo", func(t *testing.T) { + for _, et := range []struct { + proto int + typ Type + hdr []byte + obj []byte + ext Extension + }{ + // Interface information with no attribute + { + proto: iana.ProtocolICMP, + typ: ipv4.ICMPTypeDestinationUnreachable, + hdr: []byte{ + 0x20, 0x00, 0x00, 0x00, + }, + obj: []byte{ + 0x00, 0x04, 0x02, 0x00, + }, + ext: &InterfaceInfo{ + Class: classInterfaceInfo, + }, + }, + // Interface information with ifIndex and name + { + proto: iana.ProtocolICMP, + typ: ipv4.ICMPTypeDestinationUnreachable, + hdr: []byte{ + 0x20, 0x00, 0x00, 0x00, + }, + obj: []byte{ + 0x00, 0x10, 0x02, 0x0a, + 0x00, 0x00, 0x00, 0x10, + 0x08, byte('e'), byte('n'), byte('1'), + byte('0'), byte('1'), 0x00, 0x00, + }, + ext: &InterfaceInfo{ + Class: classInterfaceInfo, + Type: 0x0a, + Interface: &net.Interface{ + Index: 16, + Name: "en101", + }, + }, + }, + // Interface information with ifIndex, IPAddr, name and MTU + { + proto: iana.ProtocolIPv6ICMP, + typ: ipv6.ICMPTypeDestinationUnreachable, + hdr: []byte{ + 0x20, 0x00, 0x00, 0x00, + }, + obj: []byte{ + 0x00, 0x28, 0x02, 0x0f, + 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x02, 0x00, 0x00, + 0xfe, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + 0x08, byte('e'), byte('n'), byte('1'), + byte('0'), byte('1'), 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, + }, + ext: &InterfaceInfo{ + Class: classInterfaceInfo, + Type: 0x0f, + Interface: &net.Interface{ + Index: 15, + Name: "en101", + MTU: 8192, + }, + Addr: &net.IPAddr{ + IP: net.ParseIP("fe80::1"), + Zone: "en101", + }, + }, + }, + } { + if err := fn(t, et.proto, et.typ, et.hdr, et.obj, et.ext); err != nil { + t.Error(err) + } + } + }) + t.Run("InterfaceIdent", func(t *testing.T) { + for _, et := range []struct { + proto int + typ Type + hdr []byte + obj []byte + ext Extension + }{ + // Interface identification by name + { + proto: iana.ProtocolICMP, + typ: ipv4.ICMPTypeExtendedEchoRequest, + hdr: []byte{ + 0x20, 0x00, 0x00, 0x00, + }, + obj: []byte{ + 0x00, 0x0c, 0x03, 0x01, + byte('e'), byte('n'), byte('1'), byte('0'), + byte('1'), 0x00, 0x00, 0x00, + }, + ext: &InterfaceIdent{ + Class: classInterfaceIdent, + Type: typeInterfaceByName, + Name: "en101", + }, + }, + // Interface identification by index + { + proto: iana.ProtocolIPv6ICMP, + typ: ipv6.ICMPTypeExtendedEchoRequest, + hdr: []byte{ + 0x20, 0x00, 0x00, 0x00, + }, + obj: []byte{ + 0x00, 0x0c, 0x03, 0x02, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x8f, + }, + ext: &InterfaceIdent{ + Class: classInterfaceIdent, + Type: typeInterfaceByIndex, + Index: 911, + }, + }, + // Interface identification by address + { + proto: iana.ProtocolICMP, + typ: ipv4.ICMPTypeExtendedEchoRequest, + hdr: []byte{ + 0x20, 0x00, 0x00, 0x00, + }, + obj: []byte{ + 0x00, 0x10, 0x03, 0x03, + byte(iana.AddrFamily48bitMAC >> 8), byte(iana.AddrFamily48bitMAC & 0x0f), 0x06, 0x00, + 0x01, 0x23, 0x45, 0x67, + 0x89, 0xab, 0x00, 0x00, + }, + ext: &InterfaceIdent{ + Class: classInterfaceIdent, + Type: typeInterfaceByAddress, + AFI: iana.AddrFamily48bitMAC, + Addr: []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab}, + }, + }, + } { + if err := fn(t, et.proto, et.typ, et.hdr, et.obj, et.ext); err != nil { + t.Error(err) + } + } + }) } func TestParseInterfaceName(t *testing.T) { ifi := InterfaceInfo{Interface: &net.Interface{}} - for i, tt := range parseInterfaceNameTests { + for i, tt := range []struct { + b []byte + error + }{ + {[]byte{0, 'e', 'n', '0'}, errInvalidExtension}, + {[]byte{4, 'e', 'n', '0'}, nil}, + {[]byte{7, 'e', 'n', '0', 0xff, 0xff, 0xff, 0xff}, errInvalidExtension}, + {[]byte{8, 'e', 'n', '0', 0xff, 0xff, 0xff}, errMessageTooShort}, + } { if _, err := ifi.parseName(tt.b); err != tt.error { t.Errorf("#%d: got %v; want %v", i, err, tt.error) } diff --git a/vendor/golang.org/x/net/icmp/interface.go b/vendor/golang.org/x/net/icmp/interface.go index 78b5b98bf..617f757b9 100644 --- a/vendor/golang.org/x/net/icmp/interface.go +++ b/vendor/golang.org/x/net/icmp/interface.go @@ -14,9 +14,6 @@ import ( const ( classInterfaceInfo = 2 - - afiIPv4 = 1 - afiIPv6 = 2 ) const ( @@ -127,11 +124,11 @@ func (ifi *InterfaceInfo) parseIfIndex(b []byte) ([]byte, error) { func (ifi *InterfaceInfo) marshalIPAddr(proto int, b []byte) []byte { switch proto { case iana.ProtocolICMP: - binary.BigEndian.PutUint16(b[:2], uint16(afiIPv4)) + binary.BigEndian.PutUint16(b[:2], uint16(iana.AddrFamilyIPv4)) copy(b[4:4+net.IPv4len], ifi.Addr.IP.To4()) b = b[4+net.IPv4len:] case iana.ProtocolIPv6ICMP: - binary.BigEndian.PutUint16(b[:2], uint16(afiIPv6)) + binary.BigEndian.PutUint16(b[:2], uint16(iana.AddrFamilyIPv6)) copy(b[4:4+net.IPv6len], ifi.Addr.IP.To16()) b = b[4+net.IPv6len:] } @@ -145,14 +142,14 @@ func (ifi *InterfaceInfo) parseIPAddr(b []byte) ([]byte, error) { afi := int(binary.BigEndian.Uint16(b[:2])) b = b[4:] switch afi { - case afiIPv4: + case iana.AddrFamilyIPv4: if len(b) < net.IPv4len { return nil, errMessageTooShort } ifi.Addr.IP = make(net.IP, net.IPv4len) copy(ifi.Addr.IP, b[:net.IPv4len]) b = b[net.IPv4len:] - case afiIPv6: + case iana.AddrFamilyIPv6: if len(b) < net.IPv6len { return nil, errMessageTooShort } @@ -234,3 +231,92 @@ func parseInterfaceInfo(b []byte) (Extension, error) { } return ifi, nil } + +const ( + classInterfaceIdent = 3 + typeInterfaceByName = 1 + typeInterfaceByIndex = 2 + typeInterfaceByAddress = 3 +) + +// An InterfaceIdent represents interface identification. +type InterfaceIdent struct { + Class int // extension object class number + Type int // extension object sub-type + Name string // interface name + Index int // interface index + AFI int // address family identifier; see address family numbers in IANA registry + Addr []byte // address +} + +// Len implements the Len method of Extension interface. +func (ifi *InterfaceIdent) Len(_ int) int { + switch ifi.Type { + case typeInterfaceByName: + l := len(ifi.Name) + if l > 255 { + l = 255 + } + return 4 + (l+3)&^3 + case typeInterfaceByIndex: + return 4 + 8 + case typeInterfaceByAddress: + return 4 + 4 + (len(ifi.Addr)+3)&^3 + default: + return 4 + } +} + +// Marshal implements the Marshal method of Extension interface. +func (ifi *InterfaceIdent) Marshal(proto int) ([]byte, error) { + b := make([]byte, ifi.Len(proto)) + if err := ifi.marshal(proto, b); err != nil { + return nil, err + } + return b, nil +} + +func (ifi *InterfaceIdent) marshal(proto int, b []byte) error { + l := ifi.Len(proto) + binary.BigEndian.PutUint16(b[:2], uint16(l)) + b[2], b[3] = classInterfaceIdent, byte(ifi.Type) + switch ifi.Type { + case typeInterfaceByName: + copy(b[4:], ifi.Name) + case typeInterfaceByIndex: + binary.BigEndian.PutUint64(b[4:4+8], uint64(ifi.Index)) + case typeInterfaceByAddress: + binary.BigEndian.PutUint16(b[4:4+2], uint16(ifi.AFI)) + b[4+2] = byte(len(ifi.Addr)) + copy(b[4+4:], ifi.Addr) + } + return nil +} + +func parseInterfaceIdent(b []byte) (Extension, error) { + ifi := &InterfaceIdent{ + Class: int(b[2]), + Type: int(b[3]), + } + switch ifi.Type { + case typeInterfaceByName: + ifi.Name = strings.Trim(string(b[4:]), string(0)) + case typeInterfaceByIndex: + if len(b[4:]) < 8 { + return nil, errInvalidExtension + } + ifi.Index = int(binary.BigEndian.Uint64(b[4 : 4+8])) + case typeInterfaceByAddress: + if len(b[4:]) < 4 { + return nil, errInvalidExtension + } + ifi.AFI = int(binary.BigEndian.Uint16(b[4 : 4+2])) + l := int(b[4+2]) + if len(b[4+4:]) < l { + return nil, errInvalidExtension + } + ifi.Addr = make([]byte, l) + copy(ifi.Addr, b[4+4:]) + } + return ifi, nil +} diff --git a/vendor/golang.org/x/net/icmp/ipv4_test.go b/vendor/golang.org/x/net/icmp/ipv4_test.go index 058953f43..3fdee83fb 100644 --- a/vendor/golang.org/x/net/icmp/ipv4_test.go +++ b/vendor/golang.org/x/net/icmp/ipv4_test.go @@ -15,69 +15,61 @@ import ( "golang.org/x/net/ipv4" ) -type ipv4HeaderTest struct { - wireHeaderFromKernel [ipv4.HeaderLen]byte - wireHeaderFromTradBSDKernel [ipv4.HeaderLen]byte - Header *ipv4.Header -} - -var ipv4HeaderLittleEndianTest = ipv4HeaderTest{ - // TODO(mikio): Add platform dependent wire header formats when - // we support new platforms. - wireHeaderFromKernel: [ipv4.HeaderLen]byte{ - 0x45, 0x01, 0xbe, 0xef, - 0xca, 0xfe, 0x45, 0xdc, - 0xff, 0x01, 0xde, 0xad, - 172, 16, 254, 254, - 192, 168, 0, 1, - }, - wireHeaderFromTradBSDKernel: [ipv4.HeaderLen]byte{ - 0x45, 0x01, 0xef, 0xbe, - 0xca, 0xfe, 0x45, 0xdc, - 0xff, 0x01, 0xde, 0xad, - 172, 16, 254, 254, - 192, 168, 0, 1, - }, - Header: &ipv4.Header{ - Version: ipv4.Version, - Len: ipv4.HeaderLen, - TOS: 1, - TotalLen: 0xbeef, - ID: 0xcafe, - Flags: ipv4.DontFragment, - FragOff: 1500, - TTL: 255, - Protocol: 1, - Checksum: 0xdead, - Src: net.IPv4(172, 16, 254, 254), - Dst: net.IPv4(192, 168, 0, 1), - }, -} - func TestParseIPv4Header(t *testing.T) { - tt := &ipv4HeaderLittleEndianTest - if socket.NativeEndian != binary.LittleEndian { - t.Skip("no test for non-little endian machine yet") - } - - var wh []byte - switch runtime.GOOS { - case "darwin": - wh = tt.wireHeaderFromTradBSDKernel[:] - case "freebsd": - if freebsdVersion >= 1000000 { - wh = tt.wireHeaderFromKernel[:] - } else { - wh = tt.wireHeaderFromTradBSDKernel[:] - } - default: - wh = tt.wireHeaderFromKernel[:] - } - h, err := ParseIPv4Header(wh) - if err != nil { - t.Fatal(err) - } - if !reflect.DeepEqual(h, tt.Header) { - t.Fatalf("got %#v; want %#v", h, tt.Header) + switch socket.NativeEndian { + case binary.LittleEndian: + t.Run("LittleEndian", func(t *testing.T) { + // TODO(mikio): Add platform dependent wire + // header formats when we support new + // platforms. + wireHeaderFromKernel := [ipv4.HeaderLen]byte{ + 0x45, 0x01, 0xbe, 0xef, + 0xca, 0xfe, 0x45, 0xdc, + 0xff, 0x01, 0xde, 0xad, + 172, 16, 254, 254, + 192, 168, 0, 1, + } + wireHeaderFromTradBSDKernel := [ipv4.HeaderLen]byte{ + 0x45, 0x01, 0xef, 0xbe, + 0xca, 0xfe, 0x45, 0xdc, + 0xff, 0x01, 0xde, 0xad, + 172, 16, 254, 254, + 192, 168, 0, 1, + } + th := &ipv4.Header{ + Version: ipv4.Version, + Len: ipv4.HeaderLen, + TOS: 1, + TotalLen: 0xbeef, + ID: 0xcafe, + Flags: ipv4.DontFragment, + FragOff: 1500, + TTL: 255, + Protocol: 1, + Checksum: 0xdead, + Src: net.IPv4(172, 16, 254, 254), + Dst: net.IPv4(192, 168, 0, 1), + } + var wh []byte + switch runtime.GOOS { + case "darwin": + wh = wireHeaderFromTradBSDKernel[:] + case "freebsd": + if freebsdVersion >= 1000000 { + wh = wireHeaderFromKernel[:] + } else { + wh = wireHeaderFromTradBSDKernel[:] + } + default: + wh = wireHeaderFromKernel[:] + } + h, err := ParseIPv4Header(wh) + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(h, th) { + t.Fatalf("got %#v; want %#v", h, th) + } + }) } } diff --git a/vendor/golang.org/x/net/icmp/message.go b/vendor/golang.org/x/net/icmp/message.go index 81140b0df..46fe95ab0 100644 --- a/vendor/golang.org/x/net/icmp/message.go +++ b/vendor/golang.org/x/net/icmp/message.go @@ -11,6 +11,7 @@ // ICMP extensions for MPLS are defined in RFC 4950. // ICMP extensions for interface and next-hop identification are // defined in RFC 5837. +// PROBE: A utility for probing interfaces is defined in RFC 8335. package icmp // import "golang.org/x/net/icmp" import ( @@ -107,21 +108,25 @@ func (m *Message) Marshal(psh []byte) ([]byte, error) { return b[len(psh):], nil } -var parseFns = map[Type]func(int, []byte) (MessageBody, error){ +var parseFns = map[Type]func(int, Type, []byte) (MessageBody, error){ ipv4.ICMPTypeDestinationUnreachable: parseDstUnreach, ipv4.ICMPTypeTimeExceeded: parseTimeExceeded, ipv4.ICMPTypeParameterProblem: parseParamProb, - ipv4.ICMPTypeEcho: parseEcho, - ipv4.ICMPTypeEchoReply: parseEcho, + ipv4.ICMPTypeEcho: parseEcho, + ipv4.ICMPTypeEchoReply: parseEcho, + ipv4.ICMPTypeExtendedEchoRequest: parseExtendedEchoRequest, + ipv4.ICMPTypeExtendedEchoReply: parseExtendedEchoReply, ipv6.ICMPTypeDestinationUnreachable: parseDstUnreach, ipv6.ICMPTypePacketTooBig: parsePacketTooBig, ipv6.ICMPTypeTimeExceeded: parseTimeExceeded, ipv6.ICMPTypeParameterProblem: parseParamProb, - ipv6.ICMPTypeEchoRequest: parseEcho, - ipv6.ICMPTypeEchoReply: parseEcho, + ipv6.ICMPTypeEchoRequest: parseEcho, + ipv6.ICMPTypeEchoReply: parseEcho, + ipv6.ICMPTypeExtendedEchoRequest: parseExtendedEchoRequest, + ipv6.ICMPTypeExtendedEchoReply: parseExtendedEchoReply, } // ParseMessage parses b as an ICMP message. @@ -143,7 +148,7 @@ func ParseMessage(proto int, b []byte) (*Message, error) { if fn, ok := parseFns[m.Type]; !ok { m.Body, err = parseDefaultMessageBody(proto, b[4:]) } else { - m.Body, err = fn(proto, b[4:]) + m.Body, err = fn(proto, m.Type, b[4:]) } if err != nil { return nil, err diff --git a/vendor/golang.org/x/net/icmp/message_test.go b/vendor/golang.org/x/net/icmp/message_test.go index 5d2605f8d..c278b8b83 100644 --- a/vendor/golang.org/x/net/icmp/message_test.go +++ b/vendor/golang.org/x/net/icmp/message_test.go @@ -15,120 +15,141 @@ import ( "golang.org/x/net/ipv6" ) -var marshalAndParseMessageForIPv4Tests = []icmp.Message{ - { - Type: ipv4.ICMPTypeDestinationUnreachable, Code: 15, - Body: &icmp.DstUnreach{ - Data: []byte("ERROR-INVOKING-PACKET"), - }, - }, - { - Type: ipv4.ICMPTypeTimeExceeded, Code: 1, - Body: &icmp.TimeExceeded{ - Data: []byte("ERROR-INVOKING-PACKET"), - }, - }, - { - Type: ipv4.ICMPTypeParameterProblem, Code: 2, - Body: &icmp.ParamProb{ - Pointer: 8, - Data: []byte("ERROR-INVOKING-PACKET"), - }, - }, - { - Type: ipv4.ICMPTypeEcho, Code: 0, - Body: &icmp.Echo{ - ID: 1, Seq: 2, - Data: []byte("HELLO-R-U-THERE"), - }, - }, - { - Type: ipv4.ICMPTypePhoturis, - Body: &icmp.DefaultMessageBody{ - Data: []byte{0x80, 0x40, 0x20, 0x10}, - }, - }, -} - -func TestMarshalAndParseMessageForIPv4(t *testing.T) { - for i, tt := range marshalAndParseMessageForIPv4Tests { - b, err := tt.Marshal(nil) - if err != nil { - t.Fatal(err) - } - m, err := icmp.ParseMessage(iana.ProtocolICMP, b) - if err != nil { - t.Fatal(err) - } - if m.Type != tt.Type || m.Code != tt.Code { - t.Errorf("#%v: got %v; want %v", i, m, &tt) - } - if !reflect.DeepEqual(m.Body, tt.Body) { - t.Errorf("#%v: got %v; want %v", i, m.Body, tt.Body) - } - } -} - -var marshalAndParseMessageForIPv6Tests = []icmp.Message{ - { - Type: ipv6.ICMPTypeDestinationUnreachable, Code: 6, - Body: &icmp.DstUnreach{ - Data: []byte("ERROR-INVOKING-PACKET"), - }, - }, - { - Type: ipv6.ICMPTypePacketTooBig, Code: 0, - Body: &icmp.PacketTooBig{ - MTU: 1<<16 - 1, - Data: []byte("ERROR-INVOKING-PACKET"), - }, - }, - { - Type: ipv6.ICMPTypeTimeExceeded, Code: 1, - Body: &icmp.TimeExceeded{ - Data: []byte("ERROR-INVOKING-PACKET"), - }, - }, - { - Type: ipv6.ICMPTypeParameterProblem, Code: 2, - Body: &icmp.ParamProb{ - Pointer: 8, - Data: []byte("ERROR-INVOKING-PACKET"), - }, - }, - { - Type: ipv6.ICMPTypeEchoRequest, Code: 0, - Body: &icmp.Echo{ - ID: 1, Seq: 2, - Data: []byte("HELLO-R-U-THERE"), - }, - }, - { - Type: ipv6.ICMPTypeDuplicateAddressConfirmation, - Body: &icmp.DefaultMessageBody{ - Data: []byte{0x80, 0x40, 0x20, 0x10}, - }, - }, -} - -func TestMarshalAndParseMessageForIPv6(t *testing.T) { - pshicmp := icmp.IPv6PseudoHeader(net.ParseIP("fe80::1"), net.ParseIP("ff02::1")) - for i, tt := range marshalAndParseMessageForIPv6Tests { - for _, psh := range [][]byte{pshicmp, nil} { - b, err := tt.Marshal(psh) - if err != nil { - t.Fatal(err) +func TestMarshalAndParseMessage(t *testing.T) { + fn := func(t *testing.T, proto int, tms []icmp.Message) { + var pshs [][]byte + switch proto { + case iana.ProtocolICMP: + pshs = [][]byte{nil} + case iana.ProtocolIPv6ICMP: + pshs = [][]byte{ + icmp.IPv6PseudoHeader(net.ParseIP("fe80::1"), net.ParseIP("ff02::1")), + nil, } - m, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, b) - if err != nil { - t.Fatal(err) - } - if m.Type != tt.Type || m.Code != tt.Code { - t.Errorf("#%v: got %v; want %v", i, m, &tt) - } - if !reflect.DeepEqual(m.Body, tt.Body) { - t.Errorf("#%v: got %v; want %v", i, m.Body, tt.Body) + } + for i, tm := range tms { + for _, psh := range pshs { + b, err := tm.Marshal(psh) + if err != nil { + t.Fatal(err) + } + m, err := icmp.ParseMessage(proto, b) + if err != nil { + t.Fatal(err) + } + if m.Type != tm.Type || m.Code != tm.Code { + t.Errorf("#%d: got %#v; want %#v", i, m, &tm) + } + if !reflect.DeepEqual(m.Body, tm.Body) { + t.Errorf("#%d: got %#v; want %#v", i, m.Body, tm.Body) + } } } } + + t.Run("IPv4", func(t *testing.T) { + fn(t, iana.ProtocolICMP, + []icmp.Message{ + { + Type: ipv4.ICMPTypeDestinationUnreachable, Code: 15, + Body: &icmp.DstUnreach{ + Data: []byte("ERROR-INVOKING-PACKET"), + }, + }, + { + Type: ipv4.ICMPTypeTimeExceeded, Code: 1, + Body: &icmp.TimeExceeded{ + Data: []byte("ERROR-INVOKING-PACKET"), + }, + }, + { + Type: ipv4.ICMPTypeParameterProblem, Code: 2, + Body: &icmp.ParamProb{ + Pointer: 8, + Data: []byte("ERROR-INVOKING-PACKET"), + }, + }, + { + Type: ipv4.ICMPTypeEcho, Code: 0, + Body: &icmp.Echo{ + ID: 1, Seq: 2, + Data: []byte("HELLO-R-U-THERE"), + }, + }, + { + Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0, + Body: &icmp.ExtendedEchoRequest{ + ID: 1, Seq: 2, + }, + }, + { + Type: ipv4.ICMPTypeExtendedEchoReply, Code: 0, + Body: &icmp.ExtendedEchoReply{ + State: 4 /* Delay */, Active: true, IPv4: true, + }, + }, + { + Type: ipv4.ICMPTypePhoturis, + Body: &icmp.DefaultMessageBody{ + Data: []byte{0x80, 0x40, 0x20, 0x10}, + }, + }, + }) + }) + t.Run("IPv6", func(t *testing.T) { + fn(t, iana.ProtocolIPv6ICMP, + []icmp.Message{ + { + Type: ipv6.ICMPTypeDestinationUnreachable, Code: 6, + Body: &icmp.DstUnreach{ + Data: []byte("ERROR-INVOKING-PACKET"), + }, + }, + { + Type: ipv6.ICMPTypePacketTooBig, Code: 0, + Body: &icmp.PacketTooBig{ + MTU: 1<<16 - 1, + Data: []byte("ERROR-INVOKING-PACKET"), + }, + }, + { + Type: ipv6.ICMPTypeTimeExceeded, Code: 1, + Body: &icmp.TimeExceeded{ + Data: []byte("ERROR-INVOKING-PACKET"), + }, + }, + { + Type: ipv6.ICMPTypeParameterProblem, Code: 2, + Body: &icmp.ParamProb{ + Pointer: 8, + Data: []byte("ERROR-INVOKING-PACKET"), + }, + }, + { + Type: ipv6.ICMPTypeEchoRequest, Code: 0, + Body: &icmp.Echo{ + ID: 1, Seq: 2, + Data: []byte("HELLO-R-U-THERE"), + }, + }, + { + Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0, + Body: &icmp.ExtendedEchoRequest{ + ID: 1, Seq: 2, + }, + }, + { + Type: ipv6.ICMPTypeExtendedEchoReply, Code: 0, + Body: &icmp.ExtendedEchoReply{ + State: 5 /* Probe */, Active: true, IPv6: true, + }, + }, + { + Type: ipv6.ICMPTypeDuplicateAddressConfirmation, + Body: &icmp.DefaultMessageBody{ + Data: []byte{0x80, 0x40, 0x20, 0x10}, + }, + }, + }) + }) } diff --git a/vendor/golang.org/x/net/icmp/multipart.go b/vendor/golang.org/x/net/icmp/multipart.go index f27135660..9ebbbafe9 100644 --- a/vendor/golang.org/x/net/icmp/multipart.go +++ b/vendor/golang.org/x/net/icmp/multipart.go @@ -10,12 +10,14 @@ import "golang.org/x/net/internal/iana" // exts as extensions, and returns a required length for message body // and a required length for a padded original datagram in wire // format. -func multipartMessageBodyDataLen(proto int, b []byte, exts []Extension) (bodyLen, dataLen int) { +func multipartMessageBodyDataLen(proto int, withOrigDgram bool, b []byte, exts []Extension) (bodyLen, dataLen int) { for _, ext := range exts { bodyLen += ext.Len(proto) } if bodyLen > 0 { - dataLen = multipartMessageOrigDatagramLen(proto, b) + if withOrigDgram { + dataLen = multipartMessageOrigDatagramLen(proto, b) + } bodyLen += 4 // length of extension header } else { dataLen = len(b) @@ -50,8 +52,8 @@ func multipartMessageOrigDatagramLen(proto int, b []byte) int { // marshalMultipartMessageBody takes data as an original datagram and // exts as extesnsions, and returns a binary encoding of message body. // It can be used for non-multipart message bodies when exts is nil. -func marshalMultipartMessageBody(proto int, data []byte, exts []Extension) ([]byte, error) { - bodyLen, dataLen := multipartMessageBodyDataLen(proto, data, exts) +func marshalMultipartMessageBody(proto int, withOrigDgram bool, data []byte, exts []Extension) ([]byte, error) { + bodyLen, dataLen := multipartMessageBodyDataLen(proto, withOrigDgram, data, exts) b := make([]byte, 4+bodyLen) copy(b[4:], data) off := dataLen + 4 @@ -71,16 +73,23 @@ func marshalMultipartMessageBody(proto int, data []byte, exts []Extension) ([]by return nil, err } off += ext.Len(proto) + case *InterfaceIdent: + if err := ext.marshal(proto, b[off:]); err != nil { + return nil, err + } + off += ext.Len(proto) } } s := checksum(b[dataLen+4:]) b[dataLen+4+2] ^= byte(s) b[dataLen+4+3] ^= byte(s >> 8) - switch proto { - case iana.ProtocolICMP: - b[1] = byte(dataLen / 4) - case iana.ProtocolIPv6ICMP: - b[0] = byte(dataLen / 8) + if withOrigDgram { + switch proto { + case iana.ProtocolICMP: + b[1] = byte(dataLen / 4) + case iana.ProtocolIPv6ICMP: + b[0] = byte(dataLen / 8) + } } } return b, nil @@ -88,7 +97,7 @@ func marshalMultipartMessageBody(proto int, data []byte, exts []Extension) ([]by // parseMultipartMessageBody parses b as either a non-multipart // message body or a multipart message body. -func parseMultipartMessageBody(proto int, b []byte) ([]byte, []Extension, error) { +func parseMultipartMessageBody(proto int, typ Type, b []byte) ([]byte, []Extension, error) { var l int switch proto { case iana.ProtocolICMP: @@ -99,11 +108,14 @@ func parseMultipartMessageBody(proto int, b []byte) ([]byte, []Extension, error) if len(b) == 4 { return nil, nil, nil } - exts, l, err := parseExtensions(b[4:], l) + exts, l, err := parseExtensions(typ, b[4:], l) if err != nil { l = len(b) - 4 } - data := make([]byte, l) - copy(data, b[4:]) + var data []byte + if l > 0 { + data = make([]byte, l) + copy(data, b[4:]) + } return data, exts, nil } diff --git a/vendor/golang.org/x/net/icmp/multipart_test.go b/vendor/golang.org/x/net/icmp/multipart_test.go index 966ccb8da..74408827b 100644 --- a/vendor/golang.org/x/net/icmp/multipart_test.go +++ b/vendor/golang.org/x/net/icmp/multipart_test.go @@ -5,6 +5,7 @@ package icmp_test import ( + "errors" "fmt" "net" "reflect" @@ -16,425 +17,557 @@ import ( "golang.org/x/net/ipv6" ) -var marshalAndParseMultipartMessageForIPv4Tests = []icmp.Message{ - { - Type: ipv4.ICMPTypeDestinationUnreachable, Code: 15, - Body: &icmp.DstUnreach{ - Data: []byte("ERROR-INVOKING-PACKET"), - Extensions: []icmp.Extension{ - &icmp.MPLSLabelStack{ - Class: 1, - Type: 1, - Labels: []icmp.MPLSLabel{ - { - Label: 16014, - TC: 0x4, - S: true, - TTL: 255, - }, - }, - }, - &icmp.InterfaceInfo{ - Class: 2, - Type: 0x0f, - Interface: &net.Interface{ - Index: 15, - Name: "en101", - MTU: 8192, - }, - Addr: &net.IPAddr{ - IP: net.IPv4(192, 168, 0, 1).To4(), - }, - }, - }, - }, - }, - { - Type: ipv4.ICMPTypeTimeExceeded, Code: 1, - Body: &icmp.TimeExceeded{ - Data: []byte("ERROR-INVOKING-PACKET"), - Extensions: []icmp.Extension{ - &icmp.InterfaceInfo{ - Class: 2, - Type: 0x0f, - Interface: &net.Interface{ - Index: 15, - Name: "en101", - MTU: 8192, - }, - Addr: &net.IPAddr{ - IP: net.IPv4(192, 168, 0, 1).To4(), - }, - }, - &icmp.MPLSLabelStack{ - Class: 1, - Type: 1, - Labels: []icmp.MPLSLabel{ - { - Label: 16014, - TC: 0x4, - S: true, - TTL: 255, - }, - }, - }, - }, - }, - }, - { - Type: ipv4.ICMPTypeParameterProblem, Code: 2, - Body: &icmp.ParamProb{ - Pointer: 8, - Data: []byte("ERROR-INVOKING-PACKET"), - Extensions: []icmp.Extension{ - &icmp.MPLSLabelStack{ - Class: 1, - Type: 1, - Labels: []icmp.MPLSLabel{ - { - Label: 16014, - TC: 0x4, - S: true, - TTL: 255, - }, - }, - }, - &icmp.InterfaceInfo{ - Class: 2, - Type: 0x0f, - Interface: &net.Interface{ - Index: 15, - Name: "en101", - MTU: 8192, - }, - Addr: &net.IPAddr{ - IP: net.IPv4(192, 168, 0, 1).To4(), - }, - }, - &icmp.InterfaceInfo{ - Class: 2, - Type: 0x2f, - Interface: &net.Interface{ - Index: 16, - Name: "en102", - MTU: 8192, - }, - Addr: &net.IPAddr{ - IP: net.IPv4(192, 168, 0, 2).To4(), - }, - }, - }, - }, - }, -} - -func TestMarshalAndParseMultipartMessageForIPv4(t *testing.T) { - for i, tt := range marshalAndParseMultipartMessageForIPv4Tests { - b, err := tt.Marshal(nil) +func TestMarshalAndParseMultipartMessage(t *testing.T) { + fn := func(t *testing.T, proto int, tm icmp.Message) error { + b, err := tm.Marshal(nil) if err != nil { - t.Fatal(err) + return err } - if b[5] != 32 { - t.Errorf("#%v: got %v; want 32", i, b[5]) + switch tm.Type { + case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest: + default: + switch proto { + case iana.ProtocolICMP: + if b[5] != 32 { + return fmt.Errorf("got %d; want 32", b[5]) + } + case iana.ProtocolIPv6ICMP: + if b[4] != 16 { + return fmt.Errorf("got %d; want 16", b[4]) + } + default: + return fmt.Errorf("unknown protocol: %d", proto) + } } - m, err := icmp.ParseMessage(iana.ProtocolICMP, b) + m, err := icmp.ParseMessage(proto, b) if err != nil { - t.Fatal(err) + return err } - if m.Type != tt.Type || m.Code != tt.Code { - t.Errorf("#%v: got %v; want %v", i, m, &tt) + if m.Type != tm.Type || m.Code != tm.Code { + return fmt.Errorf("got %v; want %v", m, &tm) } switch m.Type { - case ipv4.ICMPTypeDestinationUnreachable: - got, want := m.Body.(*icmp.DstUnreach), tt.Body.(*icmp.DstUnreach) + case ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest: + got, want := m.Body.(*icmp.ExtendedEchoRequest), tm.Body.(*icmp.ExtendedEchoRequest) if !reflect.DeepEqual(got.Extensions, want.Extensions) { - t.Error(dumpExtensions(i, got.Extensions, want.Extensions)) + return errors.New(dumpExtensions(got.Extensions, want.Extensions)) + } + case ipv4.ICMPTypeDestinationUnreachable: + got, want := m.Body.(*icmp.DstUnreach), tm.Body.(*icmp.DstUnreach) + if !reflect.DeepEqual(got.Extensions, want.Extensions) { + return errors.New(dumpExtensions(got.Extensions, want.Extensions)) } if len(got.Data) != 128 { - t.Errorf("#%v: got %v; want 128", i, len(got.Data)) + return fmt.Errorf("got %d; want 128", len(got.Data)) } case ipv4.ICMPTypeTimeExceeded: - got, want := m.Body.(*icmp.TimeExceeded), tt.Body.(*icmp.TimeExceeded) + got, want := m.Body.(*icmp.TimeExceeded), tm.Body.(*icmp.TimeExceeded) if !reflect.DeepEqual(got.Extensions, want.Extensions) { - t.Error(dumpExtensions(i, got.Extensions, want.Extensions)) + return errors.New(dumpExtensions(got.Extensions, want.Extensions)) } if len(got.Data) != 128 { - t.Errorf("#%v: got %v; want 128", i, len(got.Data)) + return fmt.Errorf("got %d; want 128", len(got.Data)) } case ipv4.ICMPTypeParameterProblem: - got, want := m.Body.(*icmp.ParamProb), tt.Body.(*icmp.ParamProb) + got, want := m.Body.(*icmp.ParamProb), tm.Body.(*icmp.ParamProb) if !reflect.DeepEqual(got.Extensions, want.Extensions) { - t.Error(dumpExtensions(i, got.Extensions, want.Extensions)) + return errors.New(dumpExtensions(got.Extensions, want.Extensions)) } if len(got.Data) != 128 { - t.Errorf("#%v: got %v; want 128", i, len(got.Data)) + return fmt.Errorf("got %d; want 128", len(got.Data)) } + case ipv6.ICMPTypeDestinationUnreachable: + got, want := m.Body.(*icmp.DstUnreach), tm.Body.(*icmp.DstUnreach) + if !reflect.DeepEqual(got.Extensions, want.Extensions) { + return errors.New(dumpExtensions(got.Extensions, want.Extensions)) + } + if len(got.Data) != 128 { + return fmt.Errorf("got %d; want 128", len(got.Data)) + } + case ipv6.ICMPTypeTimeExceeded: + got, want := m.Body.(*icmp.TimeExceeded), tm.Body.(*icmp.TimeExceeded) + if !reflect.DeepEqual(got.Extensions, want.Extensions) { + return errors.New(dumpExtensions(got.Extensions, want.Extensions)) + } + if len(got.Data) != 128 { + return fmt.Errorf("got %d; want 128", len(got.Data)) + } + default: + return fmt.Errorf("unknown message type: %v", m.Type) } + return nil } -} -var marshalAndParseMultipartMessageForIPv6Tests = []icmp.Message{ - { - Type: ipv6.ICMPTypeDestinationUnreachable, Code: 6, - Body: &icmp.DstUnreach{ - Data: []byte("ERROR-INVOKING-PACKET"), - Extensions: []icmp.Extension{ - &icmp.MPLSLabelStack{ - Class: 1, - Type: 1, - Labels: []icmp.MPLSLabel{ - { - Label: 16014, - TC: 0x4, - S: true, - TTL: 255, + t.Run("IPv4", func(t *testing.T) { + for i, tm := range []icmp.Message{ + { + Type: ipv4.ICMPTypeDestinationUnreachable, Code: 15, + Body: &icmp.DstUnreach{ + Data: []byte("ERROR-INVOKING-PACKET"), + Extensions: []icmp.Extension{ + &icmp.MPLSLabelStack{ + Class: 1, + Type: 1, + Labels: []icmp.MPLSLabel{ + { + Label: 16014, + TC: 0x4, + S: true, + TTL: 255, + }, + }, + }, + &icmp.InterfaceInfo{ + Class: 2, + Type: 0x0f, + Interface: &net.Interface{ + Index: 15, + Name: "en101", + MTU: 8192, + }, + Addr: &net.IPAddr{ + IP: net.IPv4(192, 168, 0, 1).To4(), + }, }, }, }, - &icmp.InterfaceInfo{ - Class: 2, - Type: 0x0f, - Interface: &net.Interface{ - Index: 15, - Name: "en101", - MTU: 8192, - }, - Addr: &net.IPAddr{ - IP: net.ParseIP("fe80::1"), - Zone: "en101", - }, - }, }, - }, - }, - { - Type: ipv6.ICMPTypeTimeExceeded, Code: 1, - Body: &icmp.TimeExceeded{ - Data: []byte("ERROR-INVOKING-PACKET"), - Extensions: []icmp.Extension{ - &icmp.InterfaceInfo{ - Class: 2, - Type: 0x0f, - Interface: &net.Interface{ - Index: 15, - Name: "en101", - MTU: 8192, - }, - Addr: &net.IPAddr{ - IP: net.ParseIP("fe80::1"), - Zone: "en101", - }, - }, - &icmp.MPLSLabelStack{ - Class: 1, - Type: 1, - Labels: []icmp.MPLSLabel{ - { - Label: 16014, - TC: 0x4, - S: true, - TTL: 255, + { + Type: ipv4.ICMPTypeTimeExceeded, Code: 1, + Body: &icmp.TimeExceeded{ + Data: []byte("ERROR-INVOKING-PACKET"), + Extensions: []icmp.Extension{ + &icmp.InterfaceInfo{ + Class: 2, + Type: 0x0f, + Interface: &net.Interface{ + Index: 15, + Name: "en101", + MTU: 8192, + }, + Addr: &net.IPAddr{ + IP: net.IPv4(192, 168, 0, 1).To4(), + }, + }, + &icmp.MPLSLabelStack{ + Class: 1, + Type: 1, + Labels: []icmp.MPLSLabel{ + { + Label: 16014, + TC: 0x4, + S: true, + TTL: 255, + }, + }, }, }, }, - &icmp.InterfaceInfo{ - Class: 2, - Type: 0x2f, - Interface: &net.Interface{ - Index: 16, - Name: "en102", - MTU: 8192, - }, - Addr: &net.IPAddr{ - IP: net.ParseIP("fe80::1"), - Zone: "en102", + }, + { + Type: ipv4.ICMPTypeParameterProblem, Code: 2, + Body: &icmp.ParamProb{ + Pointer: 8, + Data: []byte("ERROR-INVOKING-PACKET"), + Extensions: []icmp.Extension{ + &icmp.MPLSLabelStack{ + Class: 1, + Type: 1, + Labels: []icmp.MPLSLabel{ + { + Label: 16014, + TC: 0x4, + S: true, + TTL: 255, + }, + }, + }, + &icmp.InterfaceInfo{ + Class: 2, + Type: 0x0f, + Interface: &net.Interface{ + Index: 15, + Name: "en101", + MTU: 8192, + }, + Addr: &net.IPAddr{ + IP: net.IPv4(192, 168, 0, 1).To4(), + }, + }, + &icmp.InterfaceInfo{ + Class: 2, + Type: 0x2f, + Interface: &net.Interface{ + Index: 16, + Name: "en102", + MTU: 8192, + }, + Addr: &net.IPAddr{ + IP: net.IPv4(192, 168, 0, 2).To4(), + }, + }, }, }, }, - }, - }, -} - -func TestMarshalAndParseMultipartMessageForIPv6(t *testing.T) { - pshicmp := icmp.IPv6PseudoHeader(net.ParseIP("fe80::1"), net.ParseIP("ff02::1")) - for i, tt := range marshalAndParseMultipartMessageForIPv6Tests { - for _, psh := range [][]byte{pshicmp, nil} { - b, err := tt.Marshal(psh) - if err != nil { - t.Fatal(err) - } - if b[4] != 16 { - t.Errorf("#%v: got %v; want 16", i, b[4]) - } - m, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, b) - if err != nil { - t.Fatal(err) - } - if m.Type != tt.Type || m.Code != tt.Code { - t.Errorf("#%v: got %v; want %v", i, m, &tt) - } - switch m.Type { - case ipv6.ICMPTypeDestinationUnreachable: - got, want := m.Body.(*icmp.DstUnreach), tt.Body.(*icmp.DstUnreach) - if !reflect.DeepEqual(got.Extensions, want.Extensions) { - t.Error(dumpExtensions(i, got.Extensions, want.Extensions)) - } - if len(got.Data) != 128 { - t.Errorf("#%v: got %v; want 128", i, len(got.Data)) - } - case ipv6.ICMPTypeTimeExceeded: - got, want := m.Body.(*icmp.TimeExceeded), tt.Body.(*icmp.TimeExceeded) - if !reflect.DeepEqual(got.Extensions, want.Extensions) { - t.Error(dumpExtensions(i, got.Extensions, want.Extensions)) - } - if len(got.Data) != 128 { - t.Errorf("#%v: got %v; want 128", i, len(got.Data)) - } + { + Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0, + Body: &icmp.ExtendedEchoRequest{ + ID: 1, Seq: 2, Local: true, + Extensions: []icmp.Extension{ + &icmp.InterfaceIdent{ + Class: 3, + Type: 1, + Name: "en101", + }, + }, + }, + }, + { + Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0, + Body: &icmp.ExtendedEchoRequest{ + ID: 1, Seq: 2, Local: true, + Extensions: []icmp.Extension{ + &icmp.InterfaceIdent{ + Class: 3, + Type: 2, + Index: 911, + }, + &icmp.InterfaceIdent{ + Class: 3, + Type: 1, + Name: "en101", + }, + }, + }, + }, + { + Type: ipv4.ICMPTypeExtendedEchoRequest, Code: 0, + Body: &icmp.ExtendedEchoRequest{ + ID: 1, Seq: 2, + Extensions: []icmp.Extension{ + &icmp.InterfaceIdent{ + Class: 3, + Type: 3, + AFI: iana.AddrFamily48bitMAC, + Addr: []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab}, + }, + }, + }, + }, + } { + if err := fn(t, iana.ProtocolICMP, tm); err != nil { + t.Errorf("#%d: %v", i, err) } } - } + }) + t.Run("IPv6", func(t *testing.T) { + for i, tm := range []icmp.Message{ + { + Type: ipv6.ICMPTypeDestinationUnreachable, Code: 6, + Body: &icmp.DstUnreach{ + Data: []byte("ERROR-INVOKING-PACKET"), + Extensions: []icmp.Extension{ + &icmp.MPLSLabelStack{ + Class: 1, + Type: 1, + Labels: []icmp.MPLSLabel{ + { + Label: 16014, + TC: 0x4, + S: true, + TTL: 255, + }, + }, + }, + &icmp.InterfaceInfo{ + Class: 2, + Type: 0x0f, + Interface: &net.Interface{ + Index: 15, + Name: "en101", + MTU: 8192, + }, + Addr: &net.IPAddr{ + IP: net.ParseIP("fe80::1"), + Zone: "en101", + }, + }, + }, + }, + }, + { + Type: ipv6.ICMPTypeTimeExceeded, Code: 1, + Body: &icmp.TimeExceeded{ + Data: []byte("ERROR-INVOKING-PACKET"), + Extensions: []icmp.Extension{ + &icmp.InterfaceInfo{ + Class: 2, + Type: 0x0f, + Interface: &net.Interface{ + Index: 15, + Name: "en101", + MTU: 8192, + }, + Addr: &net.IPAddr{ + IP: net.ParseIP("fe80::1"), + Zone: "en101", + }, + }, + &icmp.MPLSLabelStack{ + Class: 1, + Type: 1, + Labels: []icmp.MPLSLabel{ + { + Label: 16014, + TC: 0x4, + S: true, + TTL: 255, + }, + }, + }, + &icmp.InterfaceInfo{ + Class: 2, + Type: 0x2f, + Interface: &net.Interface{ + Index: 16, + Name: "en102", + MTU: 8192, + }, + Addr: &net.IPAddr{ + IP: net.ParseIP("fe80::1"), + Zone: "en102", + }, + }, + }, + }, + }, + { + Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0, + Body: &icmp.ExtendedEchoRequest{ + ID: 1, Seq: 2, Local: true, + Extensions: []icmp.Extension{ + &icmp.InterfaceIdent{ + Class: 3, + Type: 1, + Name: "en101", + }, + }, + }, + }, + { + Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0, + Body: &icmp.ExtendedEchoRequest{ + ID: 1, Seq: 2, Local: true, + Extensions: []icmp.Extension{ + &icmp.InterfaceIdent{ + Class: 3, + Type: 1, + Name: "en101", + }, + &icmp.InterfaceIdent{ + Class: 3, + Type: 2, + Index: 911, + }, + }, + }, + }, + { + Type: ipv6.ICMPTypeExtendedEchoRequest, Code: 0, + Body: &icmp.ExtendedEchoRequest{ + ID: 1, Seq: 2, + Extensions: []icmp.Extension{ + &icmp.InterfaceIdent{ + Class: 3, + Type: 3, + AFI: iana.AddrFamilyIPv4, + Addr: []byte{192, 0, 2, 1}, + }, + }, + }, + }, + } { + if err := fn(t, iana.ProtocolIPv6ICMP, tm); err != nil { + t.Errorf("#%d: %v", i, err) + } + } + }) } -func dumpExtensions(i int, gotExts, wantExts []icmp.Extension) string { +func dumpExtensions(gotExts, wantExts []icmp.Extension) string { var s string - for j, got := range gotExts { + for i, got := range gotExts { switch got := got.(type) { case *icmp.MPLSLabelStack: - want := wantExts[j].(*icmp.MPLSLabelStack) + want := wantExts[i].(*icmp.MPLSLabelStack) if !reflect.DeepEqual(got, want) { - s += fmt.Sprintf("#%v/%v: got %#v; want %#v\n", i, j, got, want) + s += fmt.Sprintf("#%d: got %#v; want %#v\n", i, got, want) } case *icmp.InterfaceInfo: - want := wantExts[j].(*icmp.InterfaceInfo) + want := wantExts[i].(*icmp.InterfaceInfo) if !reflect.DeepEqual(got, want) { - s += fmt.Sprintf("#%v/%v: got %#v, %#v, %#v; want %#v, %#v, %#v\n", i, j, got, got.Interface, got.Addr, want, want.Interface, want.Addr) + s += fmt.Sprintf("#%d: got %#v, %#v, %#v; want %#v, %#v, %#v\n", i, got, got.Interface, got.Addr, want, want.Interface, want.Addr) + } + case *icmp.InterfaceIdent: + want := wantExts[i].(*icmp.InterfaceIdent) + if !reflect.DeepEqual(got, want) { + s += fmt.Sprintf("#%d: got %#v; want %#v\n", i, got, want) } } } + if len(s) == 0 { + return "<nil>" + } return s[:len(s)-1] } -var multipartMessageBodyLenTests = []struct { - proto int - in icmp.MessageBody - out int -}{ - { - iana.ProtocolICMP, - &icmp.DstUnreach{ - Data: make([]byte, ipv4.HeaderLen), - }, - 4 + ipv4.HeaderLen, // unused and original datagram - }, - { - iana.ProtocolICMP, - &icmp.TimeExceeded{ - Data: make([]byte, ipv4.HeaderLen), - }, - 4 + ipv4.HeaderLen, // unused and original datagram - }, - { - iana.ProtocolICMP, - &icmp.ParamProb{ - Data: make([]byte, ipv4.HeaderLen), - }, - 4 + ipv4.HeaderLen, // [pointer, unused] and original datagram - }, - - { - iana.ProtocolICMP, - &icmp.ParamProb{ - Data: make([]byte, ipv4.HeaderLen), - Extensions: []icmp.Extension{ - &icmp.MPLSLabelStack{}, - }, - }, - 4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload, original datagram - }, - { - iana.ProtocolICMP, - &icmp.ParamProb{ - Data: make([]byte, 128), - Extensions: []icmp.Extension{ - &icmp.MPLSLabelStack{}, - }, - }, - 4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload and original datagram - }, - { - iana.ProtocolICMP, - &icmp.ParamProb{ - Data: make([]byte, 129), - Extensions: []icmp.Extension{ - &icmp.MPLSLabelStack{}, - }, - }, - 4 + 4 + 4 + 0 + 132, // [pointer, length, unused], extension header, object header, object payload and original datagram - }, - - { - iana.ProtocolIPv6ICMP, - &icmp.DstUnreach{ - Data: make([]byte, ipv6.HeaderLen), - }, - 4 + ipv6.HeaderLen, // unused and original datagram - }, - { - iana.ProtocolIPv6ICMP, - &icmp.PacketTooBig{ - Data: make([]byte, ipv6.HeaderLen), - }, - 4 + ipv6.HeaderLen, // mtu and original datagram - }, - { - iana.ProtocolIPv6ICMP, - &icmp.TimeExceeded{ - Data: make([]byte, ipv6.HeaderLen), - }, - 4 + ipv6.HeaderLen, // unused and original datagram - }, - { - iana.ProtocolIPv6ICMP, - &icmp.ParamProb{ - Data: make([]byte, ipv6.HeaderLen), - }, - 4 + ipv6.HeaderLen, // pointer and original datagram - }, - - { - iana.ProtocolIPv6ICMP, - &icmp.DstUnreach{ - Data: make([]byte, 127), - Extensions: []icmp.Extension{ - &icmp.MPLSLabelStack{}, - }, - }, - 4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram - }, - { - iana.ProtocolIPv6ICMP, - &icmp.DstUnreach{ - Data: make([]byte, 128), - Extensions: []icmp.Extension{ - &icmp.MPLSLabelStack{}, - }, - }, - 4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram - }, - { - iana.ProtocolIPv6ICMP, - &icmp.DstUnreach{ - Data: make([]byte, 129), - Extensions: []icmp.Extension{ - &icmp.MPLSLabelStack{}, - }, - }, - 4 + 4 + 4 + 0 + 136, // [length, unused], extension header, object header, object payload and original datagram - }, -} - func TestMultipartMessageBodyLen(t *testing.T) { - for i, tt := range multipartMessageBodyLenTests { + for i, tt := range []struct { + proto int + in icmp.MessageBody + out int + }{ + { + iana.ProtocolICMP, + &icmp.DstUnreach{ + Data: make([]byte, ipv4.HeaderLen), + }, + 4 + ipv4.HeaderLen, // unused and original datagram + }, + { + iana.ProtocolICMP, + &icmp.TimeExceeded{ + Data: make([]byte, ipv4.HeaderLen), + }, + 4 + ipv4.HeaderLen, // unused and original datagram + }, + { + iana.ProtocolICMP, + &icmp.ParamProb{ + Data: make([]byte, ipv4.HeaderLen), + }, + 4 + ipv4.HeaderLen, // [pointer, unused] and original datagram + }, + + { + iana.ProtocolICMP, + &icmp.ParamProb{ + Data: make([]byte, ipv4.HeaderLen), + Extensions: []icmp.Extension{ + &icmp.MPLSLabelStack{}, + }, + }, + 4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload, original datagram + }, + { + iana.ProtocolICMP, + &icmp.ParamProb{ + Data: make([]byte, 128), + Extensions: []icmp.Extension{ + &icmp.MPLSLabelStack{}, + }, + }, + 4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload and original datagram + }, + { + iana.ProtocolICMP, + &icmp.ParamProb{ + Data: make([]byte, 129), + Extensions: []icmp.Extension{ + &icmp.MPLSLabelStack{}, + }, + }, + 4 + 4 + 4 + 0 + 132, // [pointer, length, unused], extension header, object header, object payload and original datagram + }, + + { + iana.ProtocolIPv6ICMP, + &icmp.DstUnreach{ + Data: make([]byte, ipv6.HeaderLen), + }, + 4 + ipv6.HeaderLen, // unused and original datagram + }, + { + iana.ProtocolIPv6ICMP, + &icmp.PacketTooBig{ + Data: make([]byte, ipv6.HeaderLen), + }, + 4 + ipv6.HeaderLen, // mtu and original datagram + }, + { + iana.ProtocolIPv6ICMP, + &icmp.TimeExceeded{ + Data: make([]byte, ipv6.HeaderLen), + }, + 4 + ipv6.HeaderLen, // unused and original datagram + }, + { + iana.ProtocolIPv6ICMP, + &icmp.ParamProb{ + Data: make([]byte, ipv6.HeaderLen), + }, + 4 + ipv6.HeaderLen, // pointer and original datagram + }, + + { + iana.ProtocolIPv6ICMP, + &icmp.DstUnreach{ + Data: make([]byte, 127), + Extensions: []icmp.Extension{ + &icmp.MPLSLabelStack{}, + }, + }, + 4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram + }, + { + iana.ProtocolIPv6ICMP, + &icmp.DstUnreach{ + Data: make([]byte, 128), + Extensions: []icmp.Extension{ + &icmp.MPLSLabelStack{}, + }, + }, + 4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram + }, + { + iana.ProtocolIPv6ICMP, + &icmp.DstUnreach{ + Data: make([]byte, 129), + Extensions: []icmp.Extension{ + &icmp.MPLSLabelStack{}, + }, + }, + 4 + 4 + 4 + 0 + 136, // [length, unused], extension header, object header, object payload and original datagram + }, + + { + iana.ProtocolICMP, + &icmp.ExtendedEchoRequest{}, + 4, // [id, seq, l-bit] + }, + { + iana.ProtocolICMP, + &icmp.ExtendedEchoRequest{ + Extensions: []icmp.Extension{ + &icmp.InterfaceIdent{}, + }, + }, + 4 + 4 + 4, // [id, seq, l-bit], extension header, object header + }, + { + iana.ProtocolIPv6ICMP, + &icmp.ExtendedEchoRequest{ + Extensions: []icmp.Extension{ + &icmp.InterfaceIdent{ + Type: 3, + AFI: iana.AddrFamilyNSAP, + Addr: []byte{0x49, 0x00, 0x01, 0xaa, 0xaa, 0xbb, 0xbb, 0xcc, 0xcc, 0x00}, + }, + }, + }, + 4 + 4 + 4 + 16, // [id, seq, l-bit], extension header, object header, object payload + }, + } { if out := tt.in.Len(tt.proto); out != tt.out { t.Errorf("#%d: got %d; want %d", i, out, tt.out) } diff --git a/vendor/golang.org/x/net/icmp/packettoobig.go b/vendor/golang.org/x/net/icmp/packettoobig.go index a1c9df7bf..afbf24f1b 100644 --- a/vendor/golang.org/x/net/icmp/packettoobig.go +++ b/vendor/golang.org/x/net/icmp/packettoobig.go @@ -29,7 +29,7 @@ func (p *PacketTooBig) Marshal(proto int) ([]byte, error) { } // parsePacketTooBig parses b as an ICMP packet too big message body. -func parsePacketTooBig(proto int, b []byte) (MessageBody, error) { +func parsePacketTooBig(proto int, _ Type, b []byte) (MessageBody, error) { bodyLen := len(b) if bodyLen < 4 { return nil, errMessageTooShort diff --git a/vendor/golang.org/x/net/icmp/paramprob.go b/vendor/golang.org/x/net/icmp/paramprob.go index 0a2548daa..85872554f 100644 --- a/vendor/golang.org/x/net/icmp/paramprob.go +++ b/vendor/golang.org/x/net/icmp/paramprob.go @@ -21,7 +21,7 @@ func (p *ParamProb) Len(proto int) int { if p == nil { return 0 } - l, _ := multipartMessageBodyDataLen(proto, p.Data, p.Extensions) + l, _ := multipartMessageBodyDataLen(proto, true, p.Data, p.Extensions) return 4 + l } @@ -33,7 +33,7 @@ func (p *ParamProb) Marshal(proto int) ([]byte, error) { copy(b[4:], p.Data) return b, nil } - b, err := marshalMultipartMessageBody(proto, p.Data, p.Extensions) + b, err := marshalMultipartMessageBody(proto, true, p.Data, p.Extensions) if err != nil { return nil, err } @@ -42,7 +42,7 @@ func (p *ParamProb) Marshal(proto int) ([]byte, error) { } // parseParamProb parses b as an ICMP parameter problem message body. -func parseParamProb(proto int, b []byte) (MessageBody, error) { +func parseParamProb(proto int, typ Type, b []byte) (MessageBody, error) { if len(b) < 4 { return nil, errMessageTooShort } @@ -55,7 +55,7 @@ func parseParamProb(proto int, b []byte) (MessageBody, error) { } p.Pointer = uintptr(b[0]) var err error - p.Data, p.Extensions, err = parseMultipartMessageBody(proto, b) + p.Data, p.Extensions, err = parseMultipartMessageBody(proto, typ, b) if err != nil { return nil, err } diff --git a/vendor/golang.org/x/net/icmp/ping_test.go b/vendor/golang.org/x/net/icmp/ping_test.go deleted file mode 100644 index 3171dad11..000000000 --- a/vendor/golang.org/x/net/icmp/ping_test.go +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright 2014 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 icmp_test - -import ( - "errors" - "fmt" - "net" - "os" - "runtime" - "sync" - "testing" - "time" - - "golang.org/x/net/icmp" - "golang.org/x/net/internal/iana" - "golang.org/x/net/internal/nettest" - "golang.org/x/net/ipv4" - "golang.org/x/net/ipv6" -) - -func googleAddr(c *icmp.PacketConn, protocol int) (net.Addr, error) { - const host = "www.google.com" - ips, err := net.LookupIP(host) - if err != nil { - return nil, err - } - netaddr := func(ip net.IP) (net.Addr, error) { - switch c.LocalAddr().(type) { - case *net.UDPAddr: - return &net.UDPAddr{IP: ip}, nil - case *net.IPAddr: - return &net.IPAddr{IP: ip}, nil - default: - return nil, errors.New("neither UDPAddr nor IPAddr") - } - } - for _, ip := range ips { - switch protocol { - case iana.ProtocolICMP: - if ip.To4() != nil { - return netaddr(ip) - } - case iana.ProtocolIPv6ICMP: - if ip.To16() != nil && ip.To4() == nil { - return netaddr(ip) - } - } - } - return nil, errors.New("no A or AAAA record") -} - -type pingTest struct { - network, address string - protocol int - mtype icmp.Type -} - -var nonPrivilegedPingTests = []pingTest{ - {"udp4", "0.0.0.0", iana.ProtocolICMP, ipv4.ICMPTypeEcho}, - - {"udp6", "::", iana.ProtocolIPv6ICMP, ipv6.ICMPTypeEchoRequest}, -} - -func TestNonPrivilegedPing(t *testing.T) { - if testing.Short() { - t.Skip("avoid external network") - } - switch runtime.GOOS { - case "darwin": - case "linux": - t.Log("you may need to adjust the net.ipv4.ping_group_range kernel state") - default: - t.Skipf("not supported on %s", runtime.GOOS) - } - - for i, tt := range nonPrivilegedPingTests { - if err := doPing(tt, i); err != nil { - t.Error(err) - } - } -} - -var privilegedPingTests = []pingTest{ - {"ip4:icmp", "0.0.0.0", iana.ProtocolICMP, ipv4.ICMPTypeEcho}, - - {"ip6:ipv6-icmp", "::", iana.ProtocolIPv6ICMP, ipv6.ICMPTypeEchoRequest}, -} - -func TestPrivilegedPing(t *testing.T) { - if testing.Short() { - t.Skip("avoid external network") - } - if m, ok := nettest.SupportsRawIPSocket(); !ok { - t.Skip(m) - } - - for i, tt := range privilegedPingTests { - if err := doPing(tt, i); err != nil { - t.Error(err) - } - } -} - -func doPing(tt pingTest, seq int) error { - c, err := icmp.ListenPacket(tt.network, tt.address) - if err != nil { - return err - } - defer c.Close() - - dst, err := googleAddr(c, tt.protocol) - if err != nil { - return err - } - - if tt.network != "udp6" && tt.protocol == iana.ProtocolIPv6ICMP { - var f ipv6.ICMPFilter - f.SetAll(true) - f.Accept(ipv6.ICMPTypeDestinationUnreachable) - f.Accept(ipv6.ICMPTypePacketTooBig) - f.Accept(ipv6.ICMPTypeTimeExceeded) - f.Accept(ipv6.ICMPTypeParameterProblem) - f.Accept(ipv6.ICMPTypeEchoReply) - if err := c.IPv6PacketConn().SetICMPFilter(&f); err != nil { - return err - } - } - - wm := icmp.Message{ - Type: tt.mtype, Code: 0, - Body: &icmp.Echo{ - ID: os.Getpid() & 0xffff, Seq: 1 << uint(seq), - Data: []byte("HELLO-R-U-THERE"), - }, - } - wb, err := wm.Marshal(nil) - if err != nil { - return err - } - if n, err := c.WriteTo(wb, dst); err != nil { - return err - } else if n != len(wb) { - return fmt.Errorf("got %v; want %v", n, len(wb)) - } - - rb := make([]byte, 1500) - if err := c.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil { - return err - } - n, peer, err := c.ReadFrom(rb) - if err != nil { - return err - } - rm, err := icmp.ParseMessage(tt.protocol, rb[:n]) - if err != nil { - return err - } - switch rm.Type { - case ipv4.ICMPTypeEchoReply, ipv6.ICMPTypeEchoReply: - return nil - default: - return fmt.Errorf("got %+v from %v; want echo reply", rm, peer) - } -} - -func TestConcurrentNonPrivilegedListenPacket(t *testing.T) { - if testing.Short() { - t.Skip("avoid external network") - } - switch runtime.GOOS { - case "darwin": - case "linux": - t.Log("you may need to adjust the net.ipv4.ping_group_range kernel state") - default: - t.Skipf("not supported on %s", runtime.GOOS) - } - - network, address := "udp4", "127.0.0.1" - if !nettest.SupportsIPv4() { - network, address = "udp6", "::1" - } - const N = 1000 - var wg sync.WaitGroup - wg.Add(N) - for i := 0; i < N; i++ { - go func() { - defer wg.Done() - c, err := icmp.ListenPacket(network, address) - if err != nil { - t.Error(err) - return - } - c.Close() - }() - } - wg.Wait() -} diff --git a/vendor/golang.org/x/net/icmp/timeexceeded.go b/vendor/golang.org/x/net/icmp/timeexceeded.go index 344e15848..14e9e23cc 100644 --- a/vendor/golang.org/x/net/icmp/timeexceeded.go +++ b/vendor/golang.org/x/net/icmp/timeexceeded.go @@ -15,23 +15,23 @@ func (p *TimeExceeded) Len(proto int) int { if p == nil { return 0 } - l, _ := multipartMessageBodyDataLen(proto, p.Data, p.Extensions) + l, _ := multipartMessageBodyDataLen(proto, true, p.Data, p.Extensions) return 4 + l } // Marshal implements the Marshal method of MessageBody interface. func (p *TimeExceeded) Marshal(proto int) ([]byte, error) { - return marshalMultipartMessageBody(proto, p.Data, p.Extensions) + return marshalMultipartMessageBody(proto, true, p.Data, p.Extensions) } // parseTimeExceeded parses b as an ICMP time exceeded message body. -func parseTimeExceeded(proto int, b []byte) (MessageBody, error) { +func parseTimeExceeded(proto int, typ Type, b []byte) (MessageBody, error) { if len(b) < 4 { return nil, errMessageTooShort } p := &TimeExceeded{} var err error - p.Data, p.Extensions, err = parseMultipartMessageBody(proto, b) + p.Data, p.Extensions, err = parseMultipartMessageBody(proto, typ, b) if err != nil { return nil, err } diff --git a/vendor/golang.org/x/net/internal/iana/const.go b/vendor/golang.org/x/net/internal/iana/const.go index c9df24d95..826633e1b 100644 --- a/vendor/golang.org/x/net/internal/iana/const.go +++ b/vendor/golang.org/x/net/internal/iana/const.go @@ -1,5 +1,5 @@ // go generate gen.go -// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// Code generated by the command above; DO NOT EDIT. // Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA). package iana // import "golang.org/x/net/internal/iana" @@ -38,7 +38,7 @@ const ( CongestionExperienced = 0x3 // CE (Congestion Experienced) ) -// Protocol Numbers, Updated: 2016-06-22 +// Protocol Numbers, Updated: 2017-10-13 const ( ProtocolIP = 0 // IPv4 encapsulation, pseudo protocol number ProtocolHOPOPT = 0 // IPv6 Hop-by-Hop Option @@ -178,3 +178,50 @@ const ( ProtocolROHC = 142 // Robust Header Compression ProtocolReserved = 255 // Reserved ) + +// Address Family Numbers, Updated: 2016-10-25 +const ( + AddrFamilyIPv4 = 1 // IP (IP version 4) + AddrFamilyIPv6 = 2 // IP6 (IP version 6) + AddrFamilyNSAP = 3 // NSAP + AddrFamilyHDLC = 4 // HDLC (8-bit multidrop) + AddrFamilyBBN1822 = 5 // BBN 1822 + AddrFamily802 = 6 // 802 (includes all 802 media plus Ethernet "canonical format") + AddrFamilyE163 = 7 // E.163 + AddrFamilyE164 = 8 // E.164 (SMDS, Frame Relay, ATM) + AddrFamilyF69 = 9 // F.69 (Telex) + AddrFamilyX121 = 10 // X.121 (X.25, Frame Relay) + AddrFamilyIPX = 11 // IPX + AddrFamilyAppletalk = 12 // Appletalk + AddrFamilyDecnetIV = 13 // Decnet IV + AddrFamilyBanyanVines = 14 // Banyan Vines + AddrFamilyE164withSubaddress = 15 // E.164 with NSAP format subaddress + AddrFamilyDNS = 16 // DNS (Domain Name System) + AddrFamilyDistinguishedName = 17 // Distinguished Name + AddrFamilyASNumber = 18 // AS Number + AddrFamilyXTPoverIPv4 = 19 // XTP over IP version 4 + AddrFamilyXTPoverIPv6 = 20 // XTP over IP version 6 + AddrFamilyXTPnativemodeXTP = 21 // XTP native mode XTP + AddrFamilyFibreChannelWorldWidePortName = 22 // Fibre Channel World-Wide Port Name + AddrFamilyFibreChannelWorldWideNodeName = 23 // Fibre Channel World-Wide Node Name + AddrFamilyGWID = 24 // GWID + AddrFamilyL2VPN = 25 // AFI for L2VPN information + AddrFamilyMPLSTPSectionEndpointID = 26 // MPLS-TP Section Endpoint Identifier + AddrFamilyMPLSTPLSPEndpointID = 27 // MPLS-TP LSP Endpoint Identifier + AddrFamilyMPLSTPPseudowireEndpointID = 28 // MPLS-TP Pseudowire Endpoint Identifier + AddrFamilyMTIPv4 = 29 // MT IP: Multi-Topology IP version 4 + AddrFamilyMTIPv6 = 30 // MT IPv6: Multi-Topology IP version 6 + AddrFamilyEIGRPCommonServiceFamily = 16384 // EIGRP Common Service Family + AddrFamilyEIGRPIPv4ServiceFamily = 16385 // EIGRP IPv4 Service Family + AddrFamilyEIGRPIPv6ServiceFamily = 16386 // EIGRP IPv6 Service Family + AddrFamilyLISPCanonicalAddressFormat = 16387 // LISP Canonical Address Format (LCAF) + AddrFamilyBGPLS = 16388 // BGP-LS + AddrFamily48bitMAC = 16389 // 48-bit MAC + AddrFamily64bitMAC = 16390 // 64-bit MAC + AddrFamilyOUI = 16391 // OUI + AddrFamilyMACFinal24bits = 16392 // MAC/24 + AddrFamilyMACFinal40bits = 16393 // MAC/40 + AddrFamilyIPv6Initial64bits = 16394 // IPv6/64 + AddrFamilyRBridgePortID = 16395 // RBridge Port ID + AddrFamilyTRILLNickname = 16396 // TRILL Nickname +) diff --git a/vendor/golang.org/x/net/internal/iana/gen.go b/vendor/golang.org/x/net/internal/iana/gen.go index 2a5c310c2..2227e09e8 100644 --- a/vendor/golang.org/x/net/internal/iana/gen.go +++ b/vendor/golang.org/x/net/internal/iana/gen.go @@ -39,12 +39,16 @@ var registries = []struct { "https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml", parseProtocolNumbers, }, + { + "http://www.iana.org/assignments/address-family-numbers/address-family-numbers.xml", + parseAddrFamilyNumbers, + }, } func main() { var bb bytes.Buffer fmt.Fprintf(&bb, "// go generate gen.go\n") - fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n") + fmt.Fprintf(&bb, "// Code generated by the command above; DO NOT EDIT.\n\n") fmt.Fprintf(&bb, "// Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA).\n") fmt.Fprintf(&bb, `package iana // import "golang.org/x/net/internal/iana"`+"\n\n") for _, r := range registries { @@ -291,3 +295,93 @@ func (pn *protocolNumbers) escape() []canonProtocolRecord { } return prs } + +func parseAddrFamilyNumbers(w io.Writer, r io.Reader) error { + dec := xml.NewDecoder(r) + var afn addrFamilylNumbers + if err := dec.Decode(&afn); err != nil { + return err + } + afrs := afn.escape() + fmt.Fprintf(w, "// %s, Updated: %s\n", afn.Title, afn.Updated) + fmt.Fprintf(w, "const (\n") + for _, afr := range afrs { + if afr.Name == "" { + continue + } + fmt.Fprintf(w, "AddrFamily%s = %d", afr.Name, afr.Value) + fmt.Fprintf(w, "// %s\n", afr.Descr) + } + fmt.Fprintf(w, ")\n") + return nil +} + +type addrFamilylNumbers struct { + XMLName xml.Name `xml:"registry"` + Title string `xml:"title"` + Updated string `xml:"updated"` + RegTitle string `xml:"registry>title"` + Note string `xml:"registry>note"` + Records []struct { + Value string `xml:"value"` + Descr string `xml:"description"` + } `xml:"registry>record"` +} + +type canonAddrFamilyRecord struct { + Name string + Descr string + Value int +} + +func (afn *addrFamilylNumbers) escape() []canonAddrFamilyRecord { + afrs := make([]canonAddrFamilyRecord, len(afn.Records)) + sr := strings.NewReplacer( + "IP version 4", "IPv4", + "IP version 6", "IPv6", + "Identifier", "ID", + "-", "", + "-", "", + "/", "", + ".", "", + " ", "", + ) + for i, afr := range afn.Records { + if strings.Contains(afr.Descr, "Unassigned") || + strings.Contains(afr.Descr, "Reserved") { + continue + } + afrs[i].Descr = afr.Descr + s := strings.TrimSpace(afr.Descr) + switch s { + case "IP (IP version 4)": + afrs[i].Name = "IPv4" + case "IP6 (IP version 6)": + afrs[i].Name = "IPv6" + case "AFI for L2VPN information": + afrs[i].Name = "L2VPN" + case "E.164 with NSAP format subaddress": + afrs[i].Name = "E164withSubaddress" + case "MT IP: Multi-Topology IP version 4": + afrs[i].Name = "MTIPv4" + case "MAC/24": + afrs[i].Name = "MACFinal24bits" + case "MAC/40": + afrs[i].Name = "MACFinal40bits" + case "IPv6/64": + afrs[i].Name = "IPv6Initial64bits" + default: + n := strings.Index(s, "(") + if n > 0 { + s = s[:n] + } + n = strings.Index(s, ":") + if n > 0 { + s = s[:n] + } + afrs[i].Name = sr.Replace(s) + } + afrs[i].Value, _ = strconv.Atoi(afr.Value) + } + return afrs +} diff --git a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go index 206ea2d11..db60491fe 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go @@ -26,6 +26,11 @@ type msghdr struct { Flags int32 } +type mmsghdr struct { + Hdr msghdr + Len uint32 +} + type cmsghdr struct { Len uint32 Level int32 @@ -52,6 +57,7 @@ type sockaddrInet6 struct { const ( sizeofIovec = 0x8 sizeofMsghdr = 0x1c + sizeofMmsghdr = 0x20 sizeofCmsghdr = 0xc sizeofSockaddrInet = 0x10 diff --git a/vendor/golang.org/x/net/ipv4/gen.go b/vendor/golang.org/x/net/ipv4/gen.go index 9d490fac9..1bb1737f6 100644 --- a/vendor/golang.org/x/net/ipv4/gen.go +++ b/vendor/golang.org/x/net/ipv4/gen.go @@ -80,7 +80,7 @@ var registries = []struct { func geniana() error { var bb bytes.Buffer fmt.Fprintf(&bb, "// go generate gen.go\n") - fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n") + fmt.Fprintf(&bb, "// Code generated by the command above; DO NOT EDIT.\n\n") fmt.Fprintf(&bb, "package ipv4\n\n") for _, r := range registries { resp, err := http.Get(r.url) diff --git a/vendor/golang.org/x/net/ipv4/iana.go b/vendor/golang.org/x/net/ipv4/iana.go index be10c9488..4375b4099 100644 --- a/vendor/golang.org/x/net/ipv4/iana.go +++ b/vendor/golang.org/x/net/ipv4/iana.go @@ -1,9 +1,9 @@ // go generate gen.go -// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// Code generated by the command above; DO NOT EDIT. package ipv4 -// Internet Control Message Protocol (ICMP) Parameters, Updated: 2013-04-19 +// Internet Control Message Protocol (ICMP) Parameters, Updated: 2018-02-26 const ( ICMPTypeEchoReply ICMPType = 0 // Echo Reply ICMPTypeDestinationUnreachable ICMPType = 3 // Destination Unreachable @@ -16,9 +16,11 @@ const ( ICMPTypeTimestamp ICMPType = 13 // Timestamp ICMPTypeTimestampReply ICMPType = 14 // Timestamp Reply ICMPTypePhoturis ICMPType = 40 // Photuris + ICMPTypeExtendedEchoRequest ICMPType = 42 // Extended Echo Request + ICMPTypeExtendedEchoReply ICMPType = 43 // Extended Echo Reply ) -// Internet Control Message Protocol (ICMP) Parameters, Updated: 2013-04-19 +// Internet Control Message Protocol (ICMP) Parameters, Updated: 2018-02-26 var icmpTypes = map[ICMPType]string{ 0: "echo reply", 3: "destination unreachable", @@ -31,4 +33,6 @@ var icmpTypes = map[ICMPType]string{ 13: "timestamp", 14: "timestamp reply", 40: "photuris", + 42: "extended echo request", + 43: "extended echo reply", } diff --git a/vendor/golang.org/x/net/ipv6/gen.go b/vendor/golang.org/x/net/ipv6/gen.go index 47b7e9f0a..5885664fb 100644 --- a/vendor/golang.org/x/net/ipv6/gen.go +++ b/vendor/golang.org/x/net/ipv6/gen.go @@ -80,7 +80,7 @@ var registries = []struct { func geniana() error { var bb bytes.Buffer fmt.Fprintf(&bb, "// go generate gen.go\n") - fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n") + fmt.Fprintf(&bb, "// Code generated by the command above; DO NOT EDIT.\n\n") fmt.Fprintf(&bb, "package ipv6\n\n") for _, r := range registries { resp, err := http.Get(r.url) diff --git a/vendor/golang.org/x/net/ipv6/iana.go b/vendor/golang.org/x/net/ipv6/iana.go index 3c6214fb6..32db1aa94 100644 --- a/vendor/golang.org/x/net/ipv6/iana.go +++ b/vendor/golang.org/x/net/ipv6/iana.go @@ -1,9 +1,9 @@ // go generate gen.go -// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT +// Code generated by the command above; DO NOT EDIT. package ipv6 -// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2015-07-07 +// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2018-03-09 const ( ICMPTypeDestinationUnreachable ICMPType = 1 // Destination Unreachable ICMPTypePacketTooBig ICMPType = 2 // Packet Too Big @@ -40,9 +40,11 @@ const ( ICMPTypeDuplicateAddressRequest ICMPType = 157 // Duplicate Address Request ICMPTypeDuplicateAddressConfirmation ICMPType = 158 // Duplicate Address Confirmation ICMPTypeMPLControl ICMPType = 159 // MPL Control Message + ICMPTypeExtendedEchoRequest ICMPType = 160 // Extended Echo Request + ICMPTypeExtendedEchoReply ICMPType = 161 // Extended Echo Reply ) -// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2015-07-07 +// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2018-03-09 var icmpTypes = map[ICMPType]string{ 1: "destination unreachable", 2: "packet too big", @@ -79,4 +81,6 @@ var icmpTypes = map[ICMPType]string{ 157: "duplicate address request", 158: "duplicate address confirmation", 159: "mpl control message", + 160: "extended echo request", + 161: "extended echo reply", } diff --git a/vendor/golang.org/x/net/route/syscall.go b/vendor/golang.org/x/net/route/syscall.go index c211188b1..5f69ea63d 100644 --- a/vendor/golang.org/x/net/route/syscall.go +++ b/vendor/golang.org/x/net/route/syscall.go @@ -20,7 +20,7 @@ func sysctl(mib []int32, old *byte, oldlen *uintptr, new *byte, newlen uintptr) } else { p = unsafe.Pointer(&zero) } - _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(p), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) + _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(p), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), newlen) if errno != 0 { return error(errno) } diff --git a/vendor/golang.org/x/sync/CONTRIBUTING.md b/vendor/golang.org/x/sync/CONTRIBUTING.md index 88dff59bc..d0485e887 100644 --- a/vendor/golang.org/x/sync/CONTRIBUTING.md +++ b/vendor/golang.org/x/sync/CONTRIBUTING.md @@ -4,16 +4,15 @@ Go is an open source project. It is the work of hundreds of contributors. We appreciate your help! - ## Filing issues When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions: -1. What version of Go are you using (`go version`)? -2. What operating system and processor architecture are you using? -3. What did you do? -4. What did you expect to see? -5. What did you see instead? +1. What version of Go are you using (`go version`)? +2. What operating system and processor architecture are you using? +3. What did you do? +4. What did you expect to see? +5. What did you see instead? General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker. The gophers there will answer or ask you to file an issue if you've tripped over a bug. @@ -23,9 +22,5 @@ The gophers there will answer or ask you to file an issue if you've tripped over Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) before sending patches. -**We do not accept GitHub pull requests** -(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review). - Unless otherwise noted, the Go source files are distributed under the BSD-style license found in the LICENSE file. - diff --git a/vendor/golang.org/x/sys/CONTRIBUTING.md b/vendor/golang.org/x/sys/CONTRIBUTING.md index 88dff59bc..d0485e887 100644 --- a/vendor/golang.org/x/sys/CONTRIBUTING.md +++ b/vendor/golang.org/x/sys/CONTRIBUTING.md @@ -4,16 +4,15 @@ Go is an open source project. It is the work of hundreds of contributors. We appreciate your help! - ## Filing issues When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions: -1. What version of Go are you using (`go version`)? -2. What operating system and processor architecture are you using? -3. What did you do? -4. What did you expect to see? -5. What did you see instead? +1. What version of Go are you using (`go version`)? +2. What operating system and processor architecture are you using? +3. What did you do? +4. What did you expect to see? +5. What did you see instead? General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker. The gophers there will answer or ask you to file an issue if you've tripped over a bug. @@ -23,9 +22,5 @@ The gophers there will answer or ask you to file an issue if you've tripped over Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) before sending patches. -**We do not accept GitHub pull requests** -(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review). - Unless otherwise noted, the Go source files are distributed under the BSD-style license found in the LICENSE file. - diff --git a/vendor/golang.org/x/sys/plan9/syscall.go b/vendor/golang.org/x/sys/plan9/syscall.go index 5046cfe7f..163254cee 100644 --- a/vendor/golang.org/x/sys/plan9/syscall.go +++ b/vendor/golang.org/x/sys/plan9/syscall.go @@ -11,11 +11,14 @@ // system, set $GOOS and $GOARCH to the desired system. For example, if // you want to view documentation for freebsd/arm on linux/amd64, set $GOOS // to freebsd and $GOARCH to arm. +// // The primary use of this package is inside other packages that provide a more // portable interface to the system, such as "os", "time" and "net". Use // those packages rather than this one if you can. +// // For details of the functions and data types in this package consult // the manuals for the appropriate operating system. +// // These calls return err == nil to indicate success; otherwise // err represents an operating system error describing the failure and // holds a value of type syscall.ErrorString. diff --git a/vendor/golang.org/x/sys/unix/example_test.go b/vendor/golang.org/x/sys/unix/example_test.go new file mode 100644 index 000000000..10619afdd --- /dev/null +++ b/vendor/golang.org/x/sys/unix/example_test.go @@ -0,0 +1,19 @@ +// 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. + +// +build darwin dragonfly freebsd linux netbsd openbsd solaris + +package unix_test + +import ( + "log" + "os" + + "golang.org/x/sys/unix" +) + +func ExampleExec() { + err := unix.Exec("/bin/ls", []string{"ls", "-al"}, os.Environ()) + log.Fatal(err) +} diff --git a/vendor/golang.org/x/sys/unix/syscall.go b/vendor/golang.org/x/sys/unix/syscall.go index 857d2a42d..14690792e 100644 --- a/vendor/golang.org/x/sys/unix/syscall.go +++ b/vendor/golang.org/x/sys/unix/syscall.go @@ -11,11 +11,14 @@ // system, set $GOOS and $GOARCH to the desired system. For example, if // you want to view documentation for freebsd/arm on linux/amd64, set $GOOS // to freebsd and $GOARCH to arm. +// // The primary use of this package is inside other packages that provide a more // portable interface to the system, such as "os", "time" and "net". Use // those packages rather than this one if you can. +// // For details of the functions and data types in this package consult // the manuals for the appropriate operating system. +// // These calls return err == nil to indicate success; otherwise // err represents an operating system error describing the failure and // holds a value of type syscall.Errno. diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go index b9598694c..006e21f5d 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -330,6 +330,7 @@ func Uname(uname *Utsname) error { //sys Flock(fd int, how int) (err error) //sys Fpathconf(fd int, name int) (val int, err error) //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 +//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 //sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64 //sys Fsync(fd int) (err error) //sys Ftruncate(fd int, length int64) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go index 777860bf0..b5072de28 100644 --- a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go +++ b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go @@ -251,10 +251,12 @@ func Uname(uname *Utsname) error { //sys Fchdir(fd int) (err error) //sys Fchflags(fd int, flags int) (err error) //sys Fchmod(fd int, mode uint32) (err error) +//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchown(fd int, uid int, gid int) (err error) //sys Flock(fd int, how int) (err error) //sys Fpathconf(fd int, name int) (val int, err error) //sys Fstat(fd int, stat *Stat_t) (err error) +//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) //sys Fstatfs(fd int, stat *Statfs_t) (err error) //sys Fsync(fd int) (err error) //sys Ftruncate(fd int, length int64) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd.go b/vendor/golang.org/x/sys/unix/syscall_freebsd.go index 89f2c3fc1..79869856e 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd.go @@ -482,6 +482,7 @@ func Uname(uname *Utsname) error { //sys Flock(fd int, how int) (err error) //sys Fpathconf(fd int, name int) (val int, err error) //sys Fstat(fd int, stat *Stat_t) (err error) +//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) //sys Fstatfs(fd int, stat *Statfs_t) (err error) //sys Fsync(fd int) (err error) //sys Ftruncate(fd int, length int64) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go index c464783d8..a1e8a609b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go @@ -7,6 +7,7 @@ package unix //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fchown(fd int, uid int, gid int) (err error) //sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_gccgo.go b/vendor/golang.org/x/sys/unix/syscall_linux_gccgo.go new file mode 100644 index 000000000..df9c12371 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/syscall_linux_gccgo.go @@ -0,0 +1,21 @@ +// 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. + +// +build linux +// +build gccgo +// +build 386 arm + +package unix + +import ( + "syscall" + "unsafe" +) + +func seek(fd int, offset int64, whence int) (newoffset int64, err syscall.Errno) { + offsetLow := uint32(offset & 0xffffffff) + offsetHigh := uint32((offset >> 32) & 0xffffffff) + _, _, err = Syscall6(SYS__LLSEEK, uintptr(fd), uintptr(offsetHigh), uintptr(offsetLow), uintptr(unsafe.Pointer(&newoffset)), uintptr(whence), 0) + return newoffset, err +} diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go b/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go index 15a69cbdd..090ed404a 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go @@ -9,6 +9,7 @@ package unix //sys Dup2(oldfd int, newfd int) (err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fchown(fd int, uid int, gid int) (err error) //sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT //sys Fstatfs(fd int, buf *Statfs_t) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go b/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go index 40b8e4f0f..3d5817f66 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go @@ -15,6 +15,7 @@ import ( func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) //sys Dup2(oldfd int, newfd int) (err error) +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fchown(fd int, uid int, gid int) (err error) //sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64 //sysnb Getegid() (egid int) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go b/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go index 17c9116e8..6fb8733d6 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go @@ -9,6 +9,7 @@ package unix //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys Dup2(oldfd int, newfd int) (err error) +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fchown(fd int, uid int, gid int) (err error) //sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go b/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go index a00f99279..78c1e0df1 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go @@ -7,6 +7,7 @@ package unix //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Dup2(oldfd int, newfd int) (err error) //sys Fchown(fd int, uid int, gid int) (err error) //sys Fstat(fd int, stat *Stat_t) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_test.go b/vendor/golang.org/x/sys/unix/syscall_linux_test.go index ff7ad82b1..a2bc44015 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_test.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_test.go @@ -7,44 +7,15 @@ package unix_test import ( - "io/ioutil" "os" "runtime" + "runtime/debug" "testing" "time" "golang.org/x/sys/unix" ) -func TestFchmodat(t *testing.T) { - defer chtmpdir(t)() - - touch(t, "file1") - err := os.Symlink("file1", "symlink1") - if err != nil { - t.Fatal(err) - } - - err = unix.Fchmodat(unix.AT_FDCWD, "symlink1", 0444, 0) - if err != nil { - t.Fatalf("Fchmodat: unexpected error: %v", err) - } - - fi, err := os.Stat("file1") - if err != nil { - t.Fatal(err) - } - - if fi.Mode() != 0444 { - t.Errorf("Fchmodat: failed to change mode: expected %v, got %v", 0444, fi.Mode()) - } - - err = unix.Fchmodat(unix.AT_FDCWD, "symlink1", 0444, unix.AT_SYMLINK_NOFOLLOW) - if err != unix.EOPNOTSUPP { - t.Fatalf("Fchmodat: unexpected error: %v, expected EOPNOTSUPP", err) - } -} - func TestIoctlGetInt(t *testing.T) { f, err := os.Open("/dev/random") if err != nil { @@ -173,12 +144,46 @@ func TestUtimesNanoAt(t *testing.T) { } } -func TestGetrlimit(t *testing.T) { +func TestRlimitAs(t *testing.T) { + // disable GC during to avoid flaky test + defer debug.SetGCPercent(debug.SetGCPercent(-1)) + var rlim unix.Rlimit err := unix.Getrlimit(unix.RLIMIT_AS, &rlim) if err != nil { t.Fatalf("Getrlimit: %v", err) } + var zero unix.Rlimit + if zero == rlim { + t.Fatalf("Getrlimit: got zero value %#v", rlim) + } + set := rlim + set.Cur = uint64(unix.Getpagesize()) + err = unix.Setrlimit(unix.RLIMIT_AS, &set) + if err != nil { + t.Fatalf("Setrlimit: set failed: %#v %v", set, err) + } + + // RLIMIT_AS was set to the page size, so mmap()'ing twice the page size + // should fail. See 'man 2 getrlimit'. + _, err = unix.Mmap(-1, 0, 2*unix.Getpagesize(), unix.PROT_NONE, unix.MAP_ANON|unix.MAP_PRIVATE) + if err == nil { + t.Fatal("Mmap: unexpectedly suceeded after setting RLIMIT_AS") + } + + err = unix.Setrlimit(unix.RLIMIT_AS, &rlim) + if err != nil { + t.Fatalf("Setrlimit: restore failed: %#v %v", rlim, err) + } + + b, err := unix.Mmap(-1, 0, 2*unix.Getpagesize(), unix.PROT_NONE, unix.MAP_ANON|unix.MAP_PRIVATE) + if err != nil { + t.Fatalf("Mmap: %v", err) + } + err = unix.Munmap(b) + if err != nil { + t.Fatalf("Munmap: %v", err) + } } func TestSelect(t *testing.T) { @@ -221,47 +226,6 @@ func TestPselect(t *testing.T) { } } -func TestFstatat(t *testing.T) { - defer chtmpdir(t)() - - touch(t, "file1") - - var st1 unix.Stat_t - err := unix.Stat("file1", &st1) - if err != nil { - t.Fatalf("Stat: %v", err) - } - - var st2 unix.Stat_t - err = unix.Fstatat(unix.AT_FDCWD, "file1", &st2, 0) - if err != nil { - t.Fatalf("Fstatat: %v", err) - } - - if st1 != st2 { - t.Errorf("Fstatat: returned stat does not match Stat") - } - - err = os.Symlink("file1", "symlink1") - if err != nil { - t.Fatal(err) - } - - err = unix.Lstat("symlink1", &st1) - if err != nil { - t.Fatalf("Lstat: %v", err) - } - - err = unix.Fstatat(unix.AT_FDCWD, "symlink1", &st2, unix.AT_SYMLINK_NOFOLLOW) - if err != nil { - t.Fatalf("Fstatat: %v", err) - } - - if st1 != st2 { - t.Errorf("Fstatat: returned stat does not match Lstat") - } -} - func TestSchedSetaffinity(t *testing.T) { runtime.LockOSThread() defer runtime.UnlockOSThread() @@ -407,37 +371,3 @@ func TestStatx(t *testing.T) { t.Errorf("Statx: returned stat mtime does not match Lstat") } } - -// utilities taken from os/os_test.go - -func touch(t *testing.T, name string) { - f, err := os.Create(name) - if err != nil { - t.Fatal(err) - } - if err := f.Close(); err != nil { - t.Fatal(err) - } -} - -// chtmpdir changes the working directory to a new temporary directory and -// provides a cleanup function. Used when PWD is read-only. -func chtmpdir(t *testing.T) func() { - oldwd, err := os.Getwd() - if err != nil { - t.Fatalf("chtmpdir: %v", err) - } - d, err := ioutil.TempDir("", "test") - if err != nil { - t.Fatalf("chtmpdir: %v", err) - } - if err := os.Chdir(d); err != nil { - t.Fatalf("chtmpdir: %v", err) - } - return func() { - if err := os.Chdir(oldwd); err != nil { - t.Fatalf("chtmpdir: %v", err) - } - os.RemoveAll(d) - } -} diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd.go b/vendor/golang.org/x/sys/unix/syscall_netbsd.go index 71b707838..e1a3baa23 100644 --- a/vendor/golang.org/x/sys/unix/syscall_netbsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_netbsd.go @@ -233,13 +233,16 @@ func Uname(uname *Utsname) error { //sys Dup(fd int) (nfd int, err error) //sys Dup2(from int, to int) (err error) //sys Exit(code int) +//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_POSIX_FADVISE //sys Fchdir(fd int) (err error) //sys Fchflags(fd int, flags int) (err error) //sys Fchmod(fd int, mode uint32) (err error) +//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchown(fd int, uid int, gid int) (err error) //sys Flock(fd int, how int) (err error) //sys Fpathconf(fd int, name int) (val int, err error) //sys Fstat(fd int, stat *Stat_t) (err error) +//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) //sys Fsync(fd int) (err error) //sys Ftruncate(fd int, length int64) (err error) //sysnb Getegid() (egid int) @@ -320,7 +323,6 @@ func Uname(uname *Utsname) error { // __msync13 // __ntp_gettime30 // __posix_chown -// __posix_fadvise50 // __posix_fchown // __posix_lchown // __posix_rename diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd.go b/vendor/golang.org/x/sys/unix/syscall_openbsd.go index 37556e775..387e1cfcf 100644 --- a/vendor/golang.org/x/sys/unix/syscall_openbsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_openbsd.go @@ -204,10 +204,12 @@ func Uname(uname *Utsname) error { //sys Fchdir(fd int) (err error) //sys Fchflags(fd int, flags int) (err error) //sys Fchmod(fd int, mode uint32) (err error) +//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchown(fd int, uid int, gid int) (err error) //sys Flock(fd int, how int) (err error) //sys Fpathconf(fd int, name int) (val int, err error) //sys Fstat(fd int, stat *Stat_t) (err error) +//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) //sys Fstatfs(fd int, stat *Statfs_t) (err error) //sys Fsync(fd int) (err error) //sys Ftruncate(fd int, length int64) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go index eca8d1d09..f4d2a3451 100644 --- a/vendor/golang.org/x/sys/unix/syscall_solaris.go +++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go @@ -595,9 +595,10 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { //sys Fchown(fd int, uid int, gid int) (err error) //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) //sys Fdatasync(fd int) (err error) -//sys Flock(fd int, how int) (err error) +//sys Flock(fd int, how int) (err error) //sys Fpathconf(fd int, name int) (val int, err error) //sys Fstat(fd int, stat *Stat_t) (err error) +//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) //sys Fstatvfs(fd int, vfsstat *Statvfs_t) (err error) //sys Getdents(fd int, buf []byte, basep *uintptr) (n int, err error) //sysnb Getgid() (gid int) diff --git a/vendor/golang.org/x/sys/unix/syscall_unix.go b/vendor/golang.org/x/sys/unix/syscall_unix.go index 80b05a406..95ce5557e 100644 --- a/vendor/golang.org/x/sys/unix/syscall_unix.go +++ b/vendor/golang.org/x/sys/unix/syscall_unix.go @@ -305,3 +305,12 @@ func SetNonblock(fd int, nonblocking bool) (err error) { _, err = fcntl(fd, F_SETFL, flag) return err } + +// Exec calls execve(2), which replaces the calling executable in the process +// tree. argv0 should be the full path to an executable ("/bin/ls") and the +// executable name should also be the first argument in argv (["ls", "-l"]). +// envv are the environment variables that should be passed to the new +// process (["USER=go", "PWD=/tmp"]). +func Exec(argv0 string, argv []string, envv []string) error { + return syscall.Exec(argv0, argv, envv) +} diff --git a/vendor/golang.org/x/sys/unix/syscall_unix_test.go b/vendor/golang.org/x/sys/unix/syscall_unix_test.go index 496e47135..bbdb6fa33 100644 --- a/vendor/golang.org/x/sys/unix/syscall_unix_test.go +++ b/vendor/golang.org/x/sys/unix/syscall_unix_test.go @@ -426,6 +426,101 @@ func TestGetwd(t *testing.T) { } } +func TestFstatat(t *testing.T) { + defer chtmpdir(t)() + + touch(t, "file1") + + var st1 unix.Stat_t + err := unix.Stat("file1", &st1) + if err != nil { + t.Fatalf("Stat: %v", err) + } + + var st2 unix.Stat_t + err = unix.Fstatat(unix.AT_FDCWD, "file1", &st2, 0) + if err != nil { + t.Fatalf("Fstatat: %v", err) + } + + if st1 != st2 { + t.Errorf("Fstatat: returned stat does not match Stat") + } + + err = os.Symlink("file1", "symlink1") + if err != nil { + t.Fatal(err) + } + + err = unix.Lstat("symlink1", &st1) + if err != nil { + t.Fatalf("Lstat: %v", err) + } + + err = unix.Fstatat(unix.AT_FDCWD, "symlink1", &st2, unix.AT_SYMLINK_NOFOLLOW) + if err != nil { + t.Fatalf("Fstatat: %v", err) + } + + if st1 != st2 { + t.Errorf("Fstatat: returned stat does not match Lstat") + } +} + +func TestFchmodat(t *testing.T) { + defer chtmpdir(t)() + + touch(t, "file1") + err := os.Symlink("file1", "symlink1") + if err != nil { + t.Fatal(err) + } + + mode := os.FileMode(0444) + err = unix.Fchmodat(unix.AT_FDCWD, "symlink1", uint32(mode), 0) + if err != nil { + t.Fatalf("Fchmodat: unexpected error: %v", err) + } + + fi, err := os.Stat("file1") + if err != nil { + t.Fatal(err) + } + + if fi.Mode() != mode { + t.Errorf("Fchmodat: failed to change file mode: expected %v, got %v", mode, fi.Mode()) + } + + mode = os.FileMode(0644) + didChmodSymlink := true + err = unix.Fchmodat(unix.AT_FDCWD, "symlink1", uint32(mode), unix.AT_SYMLINK_NOFOLLOW) + if err != nil { + if (runtime.GOOS == "linux" || runtime.GOOS == "solaris") && err == unix.EOPNOTSUPP { + // Linux and Illumos don't support flags != 0 + didChmodSymlink = false + } else { + t.Fatalf("Fchmodat: unexpected error: %v", err) + } + } + + if !didChmodSymlink { + // Didn't change mode of the symlink. On Linux, the permissions + // of a symbolic link are always 0777 according to symlink(7) + mode = os.FileMode(0777) + } + + var st unix.Stat_t + err = unix.Lstat("symlink1", &st) + if err != nil { + t.Fatal(err) + } + + got := os.FileMode(st.Mode & 0777) + if got != mode { + t.Errorf("Fchmodat: failed to change symlink mode: expected %v, got %v", mode, got) + } +} + // mktmpfifo creates a temporary FIFO and provides a cleanup function. func mktmpfifo(t *testing.T) (*os.File, func()) { err := unix.Mkfifo("fifo", 0666) @@ -444,3 +539,37 @@ func mktmpfifo(t *testing.T) (*os.File, func()) { os.Remove("fifo") } } + +// utilities taken from os/os_test.go + +func touch(t *testing.T, name string) { + f, err := os.Create(name) + if err != nil { + t.Fatal(err) + } + if err := f.Close(); err != nil { + t.Fatal(err) + } +} + +// chtmpdir changes the working directory to a new temporary directory and +// provides a cleanup function. Used when PWD is read-only. +func chtmpdir(t *testing.T) func() { + oldwd, err := os.Getwd() + if err != nil { + t.Fatalf("chtmpdir: %v", err) + } + d, err := ioutil.TempDir("", "test") + if err != nil { + t.Fatalf("chtmpdir: %v", err) + } + if err := os.Chdir(d); err != nil { + t.Fatalf("chtmpdir: %v", err) + } + return func() { + if err := os.Chdir(oldwd); err != nil { + t.Fatalf("chtmpdir: %v", err) + } + os.RemoveAll(d) + } +} diff --git a/vendor/golang.org/x/sys/unix/types_netbsd.go b/vendor/golang.org/x/sys/unix/types_netbsd.go index 10aa9b3a4..1494aafcb 100644 --- a/vendor/golang.org/x/sys/unix/types_netbsd.go +++ b/vendor/golang.org/x/sys/unix/types_netbsd.go @@ -118,6 +118,17 @@ const ( PathMax = C.PATH_MAX ) +// Advice to Fadvise + +const ( + FADV_NORMAL = C.POSIX_FADV_NORMAL + FADV_RANDOM = C.POSIX_FADV_RANDOM + FADV_SEQUENTIAL = C.POSIX_FADV_SEQUENTIAL + FADV_WILLNEED = C.POSIX_FADV_WILLNEED + FADV_DONTNEED = C.POSIX_FADV_DONTNEED + FADV_NOREUSE = C.POSIX_FADV_NOREUSE +) + // Sockets type RawSockaddrInet4 C.struct_sockaddr_in diff --git a/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go index d96015505..474441b80 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go @@ -980,7 +980,10 @@ const ( RLIMIT_CPU = 0x0 RLIMIT_DATA = 0x2 RLIMIT_FSIZE = 0x1 + RLIMIT_MEMLOCK = 0x6 RLIMIT_NOFILE = 0x8 + RLIMIT_NPROC = 0x7 + RLIMIT_RSS = 0x5 RLIMIT_STACK = 0x3 RLIM_INFINITY = 0x7fffffffffffffff RTAX_AUTHOR = 0x6 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go index 763ae4fbb..4c9f72756 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go @@ -693,6 +693,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go index d6808e072..256237773 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go @@ -693,6 +693,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go index 6ae95e6b9..4ae787e49 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go @@ -693,6 +693,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go index ca6a7ea8b..14ed6886c 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go @@ -693,6 +693,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go index a0241de19..91f36e9ec 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go @@ -618,6 +618,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -659,6 +674,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go index fd9ca5a4a..a86434a7b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go @@ -924,6 +924,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go index a9f18b22d..040e2f760 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go @@ -924,6 +924,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go index 9823e18a1..cddc5e86b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go @@ -924,6 +924,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go index 8f276d65f..8c9e26a0a 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go @@ -1541,6 +1541,16 @@ func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go index 61169b331..8dc2b58f5 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go @@ -1534,6 +1534,16 @@ func Dup2(oldfd int, newfd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall9(SYS_FADVISE64, uintptr(fd), 0, uintptr(offset>>32), uintptr(offset), uintptr(length>>32), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go index 4cb59b4a5..e8beef850 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go @@ -1551,6 +1551,16 @@ func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go index 0b547ae30..899e4403a 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go @@ -1551,6 +1551,16 @@ func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go index cd94d3a83..7a477cbde 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go @@ -1534,6 +1534,16 @@ func Dup2(oldfd int, newfd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall9(SYS_FADVISE64, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(length), uintptr(length>>32), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go index cdad555a5..9dc4c7d6d 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go @@ -1551,6 +1551,16 @@ func Dup2(oldfd int, newfd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go index 38f4e44b6..f0d1ee125 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go @@ -1551,6 +1551,16 @@ func Dup2(oldfd int, newfd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go index 2dd98434e..c01b3b6ba 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go @@ -1222,6 +1222,16 @@ func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Dup2(oldfd int, newfd int) (err error) { _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go index 62eadff1c..fb4b96278 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go @@ -571,6 +571,16 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall9(SYS_POSIX_FADVISE, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), 0, uintptr(length), uintptr(length>>32), uintptr(advice), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchdir(fd int) (err error) { _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) if e1 != 0 { @@ -601,6 +611,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -642,6 +667,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go index 307f4e99e..beac82ef8 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go @@ -571,6 +571,16 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall6(SYS_POSIX_FADVISE, uintptr(fd), 0, uintptr(offset), 0, uintptr(length), uintptr(advice)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchdir(fd int) (err error) { _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) if e1 != 0 { @@ -601,6 +611,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -642,6 +667,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go index 61109313c..7bd5f60b0 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go @@ -571,6 +571,16 @@ func Exit(code int) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fadvise(fd int, offset int64, length int64, advice int) (err error) { + _, _, e1 := Syscall9(SYS_POSIX_FADVISE, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), 0, uintptr(length), uintptr(length>>32), uintptr(advice), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchdir(fd int) (err error) { _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) if e1 != 0 { @@ -601,6 +611,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -642,6 +667,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fsync(fd int) (err error) { _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go index 003f820e6..5c09c0758 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go @@ -599,6 +599,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -640,6 +655,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go index ba0e8f329..54ccc935d 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go @@ -599,6 +599,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -640,6 +655,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go index 2ce02c7c4..59258b0a4 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go @@ -599,6 +599,21 @@ func Fchmod(fd int, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) if e1 != 0 { @@ -640,6 +655,21 @@ func Fstat(fd int, stat *Stat_t) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstatfs(fd int, stat *Statfs_t) (err error) { _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go index f5d01b3a8..5e88619c4 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go @@ -50,6 +50,7 @@ import ( //go:cgo_import_dynamic libc_flock flock "libc.so" //go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so" //go:cgo_import_dynamic libc_fstat fstat "libc.so" +//go:cgo_import_dynamic libc_fstatat fstatat "libc.so" //go:cgo_import_dynamic libc_fstatvfs fstatvfs "libc.so" //go:cgo_import_dynamic libc_getdents getdents "libc.so" //go:cgo_import_dynamic libc_getgid getgid "libc.so" @@ -176,6 +177,7 @@ import ( //go:linkname procFlock libc_flock //go:linkname procFpathconf libc_fpathconf //go:linkname procFstat libc_fstat +//go:linkname procFstatat libc_fstatat //go:linkname procFstatvfs libc_fstatvfs //go:linkname procGetdents libc_getdents //go:linkname procGetgid libc_getgid @@ -303,6 +305,7 @@ var ( procFlock, procFpathconf, procFstat, + procFstatat, procFstatvfs, procGetdents, procGetgid, @@ -772,6 +775,19 @@ func Fstat(fd int, stat *Stat_t) (err error) { return } +func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFstatat)), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) + if e1 != 0 { + err = e1 + } + return +} + func Fstatvfs(fd int, vfsstat *Statvfs_t) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFstatvfs)), 2, uintptr(fd), uintptr(unsafe.Pointer(vfsstat)), 0, 0, 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go index e3b8ebb01..315a553bd 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go @@ -108,7 +108,7 @@ type Statfs_t struct { Owner uint32 Type int32 Flags int32 - Pad_cgo_0 [4]byte + _ [4]byte Syncwrites int64 Asyncwrites int64 Fstypename [16]int8 @@ -118,7 +118,7 @@ type Statfs_t struct { Spares1 int16 Mntfromname [80]int8 Spares2 int16 - Pad_cgo_1 [4]byte + _ [4]byte Spare [2]int64 } @@ -219,10 +219,10 @@ type IPv6Mreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen int32 - Pad_cgo_1 [4]byte + _ [4]byte Control *byte Controllen uint32 Flags int32 @@ -294,14 +294,14 @@ const ( ) type IfMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Data IfData + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Data IfData } type IfData struct { @@ -311,7 +311,7 @@ type IfData struct { Hdrlen uint8 Recvquota uint8 Xmitquota uint8 - Pad_cgo_0 [2]byte + _ [2]byte Mtu uint64 Metric uint64 Link_state uint64 @@ -333,24 +333,24 @@ type IfData struct { } type IfaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Metric int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Metric int32 } type IfmaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte } type IfAnnounceMsghdr struct { @@ -363,19 +363,19 @@ type IfAnnounceMsghdr struct { } type RtMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Index uint16 - Pad_cgo_0 [2]byte - Flags int32 - Addrs int32 - Pid int32 - Seq int32 - Errno int32 - Use int32 - Inits uint64 - Rmx RtMetrics + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + _ [2]byte + Flags int32 + Addrs int32 + Pid int32 + Seq int32 + Errno int32 + Use int32 + Inits uint64 + Rmx RtMetrics } type RtMetrics struct { @@ -391,7 +391,7 @@ type RtMetrics struct { Hopcount uint64 Mssopt uint16 Pad uint16 - Pad_cgo_0 [4]byte + _ [4]byte Msl uint64 Iwmaxsegs uint64 Iwcapsegs uint64 @@ -416,9 +416,9 @@ type BpfStat struct { } type BpfProgram struct { - Len uint32 - Pad_cgo_0 [4]byte - Insns *BpfInsn + Len uint32 + _ [4]byte + Insns *BpfInsn } type BpfInsn struct { @@ -429,11 +429,11 @@ type BpfInsn struct { } type BpfHdr struct { - Tstamp Timeval - Caplen uint32 - Datalen uint32 - Hdrlen uint16 - Pad_cgo_0 [6]byte + Tstamp Timeval + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + _ [6]byte } type Termios struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go index 9dbbb1ce5..8e7384b89 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go @@ -376,97 +376,123 @@ const ( ) const ( - IFA_UNSPEC = 0x0 - IFA_ADDRESS = 0x1 - IFA_LOCAL = 0x2 - IFA_LABEL = 0x3 - IFA_BROADCAST = 0x4 - IFA_ANYCAST = 0x5 - IFA_CACHEINFO = 0x6 - IFA_MULTICAST = 0x7 - IFLA_UNSPEC = 0x0 - IFLA_ADDRESS = 0x1 - IFLA_BROADCAST = 0x2 - IFLA_IFNAME = 0x3 - IFLA_MTU = 0x4 - IFLA_LINK = 0x5 - IFLA_QDISC = 0x6 - IFLA_STATS = 0x7 - IFLA_COST = 0x8 - IFLA_PRIORITY = 0x9 - IFLA_MASTER = 0xa - IFLA_WIRELESS = 0xb - IFLA_PROTINFO = 0xc - IFLA_TXQLEN = 0xd - IFLA_MAP = 0xe - IFLA_WEIGHT = 0xf - IFLA_OPERSTATE = 0x10 - IFLA_LINKMODE = 0x11 - IFLA_LINKINFO = 0x12 - IFLA_NET_NS_PID = 0x13 - IFLA_IFALIAS = 0x14 - IFLA_MAX = 0x2a - RT_SCOPE_UNIVERSE = 0x0 - RT_SCOPE_SITE = 0xc8 - RT_SCOPE_LINK = 0xfd - RT_SCOPE_HOST = 0xfe - RT_SCOPE_NOWHERE = 0xff - RT_TABLE_UNSPEC = 0x0 - RT_TABLE_COMPAT = 0xfc - RT_TABLE_DEFAULT = 0xfd - RT_TABLE_MAIN = 0xfe - RT_TABLE_LOCAL = 0xff - RT_TABLE_MAX = 0xffffffff - RTA_UNSPEC = 0x0 - RTA_DST = 0x1 - RTA_SRC = 0x2 - RTA_IIF = 0x3 - RTA_OIF = 0x4 - RTA_GATEWAY = 0x5 - RTA_PRIORITY = 0x6 - RTA_PREFSRC = 0x7 - RTA_METRICS = 0x8 - RTA_MULTIPATH = 0x9 - RTA_FLOW = 0xb - RTA_CACHEINFO = 0xc - RTA_TABLE = 0xf - RTN_UNSPEC = 0x0 - RTN_UNICAST = 0x1 - RTN_LOCAL = 0x2 - RTN_BROADCAST = 0x3 - RTN_ANYCAST = 0x4 - RTN_MULTICAST = 0x5 - RTN_BLACKHOLE = 0x6 - RTN_UNREACHABLE = 0x7 - RTN_PROHIBIT = 0x8 - RTN_THROW = 0x9 - RTN_NAT = 0xa - RTN_XRESOLVE = 0xb - RTNLGRP_NONE = 0x0 - RTNLGRP_LINK = 0x1 - RTNLGRP_NOTIFY = 0x2 - RTNLGRP_NEIGH = 0x3 - RTNLGRP_TC = 0x4 - RTNLGRP_IPV4_IFADDR = 0x5 - RTNLGRP_IPV4_MROUTE = 0x6 - RTNLGRP_IPV4_ROUTE = 0x7 - RTNLGRP_IPV4_RULE = 0x8 - RTNLGRP_IPV6_IFADDR = 0x9 - RTNLGRP_IPV6_MROUTE = 0xa - RTNLGRP_IPV6_ROUTE = 0xb - RTNLGRP_IPV6_IFINFO = 0xc - RTNLGRP_IPV6_PREFIX = 0x12 - RTNLGRP_IPV6_RULE = 0x13 - RTNLGRP_ND_USEROPT = 0x14 - SizeofNlMsghdr = 0x10 - SizeofNlMsgerr = 0x14 - SizeofRtGenmsg = 0x1 - SizeofNlAttr = 0x4 - SizeofRtAttr = 0x4 - SizeofIfInfomsg = 0x10 - SizeofIfAddrmsg = 0x8 - SizeofRtMsg = 0xc - SizeofRtNexthop = 0x8 + IFA_UNSPEC = 0x0 + IFA_ADDRESS = 0x1 + IFA_LOCAL = 0x2 + IFA_LABEL = 0x3 + IFA_BROADCAST = 0x4 + IFA_ANYCAST = 0x5 + IFA_CACHEINFO = 0x6 + IFA_MULTICAST = 0x7 + IFLA_UNSPEC = 0x0 + IFLA_ADDRESS = 0x1 + IFLA_BROADCAST = 0x2 + IFLA_IFNAME = 0x3 + IFLA_MTU = 0x4 + IFLA_LINK = 0x5 + IFLA_QDISC = 0x6 + IFLA_STATS = 0x7 + IFLA_COST = 0x8 + IFLA_PRIORITY = 0x9 + IFLA_MASTER = 0xa + IFLA_WIRELESS = 0xb + IFLA_PROTINFO = 0xc + IFLA_TXQLEN = 0xd + IFLA_MAP = 0xe + IFLA_WEIGHT = 0xf + IFLA_OPERSTATE = 0x10 + IFLA_LINKMODE = 0x11 + IFLA_LINKINFO = 0x12 + IFLA_NET_NS_PID = 0x13 + IFLA_IFALIAS = 0x14 + IFLA_NUM_VF = 0x15 + IFLA_VFINFO_LIST = 0x16 + IFLA_STATS64 = 0x17 + IFLA_VF_PORTS = 0x18 + IFLA_PORT_SELF = 0x19 + IFLA_AF_SPEC = 0x1a + IFLA_GROUP = 0x1b + IFLA_NET_NS_FD = 0x1c + IFLA_EXT_MASK = 0x1d + IFLA_PROMISCUITY = 0x1e + IFLA_NUM_TX_QUEUES = 0x1f + IFLA_NUM_RX_QUEUES = 0x20 + IFLA_CARRIER = 0x21 + IFLA_PHYS_PORT_ID = 0x22 + IFLA_CARRIER_CHANGES = 0x23 + IFLA_PHYS_SWITCH_ID = 0x24 + IFLA_LINK_NETNSID = 0x25 + IFLA_PHYS_PORT_NAME = 0x26 + IFLA_PROTO_DOWN = 0x27 + IFLA_GSO_MAX_SEGS = 0x28 + IFLA_GSO_MAX_SIZE = 0x29 + IFLA_PAD = 0x2a + IFLA_XDP = 0x2b + IFLA_EVENT = 0x2c + IFLA_NEW_NETNSID = 0x2d + IFLA_IF_NETNSID = 0x2e + IFLA_MAX = 0x2e + RT_SCOPE_UNIVERSE = 0x0 + RT_SCOPE_SITE = 0xc8 + RT_SCOPE_LINK = 0xfd + RT_SCOPE_HOST = 0xfe + RT_SCOPE_NOWHERE = 0xff + RT_TABLE_UNSPEC = 0x0 + RT_TABLE_COMPAT = 0xfc + RT_TABLE_DEFAULT = 0xfd + RT_TABLE_MAIN = 0xfe + RT_TABLE_LOCAL = 0xff + RT_TABLE_MAX = 0xffffffff + RTA_UNSPEC = 0x0 + RTA_DST = 0x1 + RTA_SRC = 0x2 + RTA_IIF = 0x3 + RTA_OIF = 0x4 + RTA_GATEWAY = 0x5 + RTA_PRIORITY = 0x6 + RTA_PREFSRC = 0x7 + RTA_METRICS = 0x8 + RTA_MULTIPATH = 0x9 + RTA_FLOW = 0xb + RTA_CACHEINFO = 0xc + RTA_TABLE = 0xf + RTN_UNSPEC = 0x0 + RTN_UNICAST = 0x1 + RTN_LOCAL = 0x2 + RTN_BROADCAST = 0x3 + RTN_ANYCAST = 0x4 + RTN_MULTICAST = 0x5 + RTN_BLACKHOLE = 0x6 + RTN_UNREACHABLE = 0x7 + RTN_PROHIBIT = 0x8 + RTN_THROW = 0x9 + RTN_NAT = 0xa + RTN_XRESOLVE = 0xb + RTNLGRP_NONE = 0x0 + RTNLGRP_LINK = 0x1 + RTNLGRP_NOTIFY = 0x2 + RTNLGRP_NEIGH = 0x3 + RTNLGRP_TC = 0x4 + RTNLGRP_IPV4_IFADDR = 0x5 + RTNLGRP_IPV4_MROUTE = 0x6 + RTNLGRP_IPV4_ROUTE = 0x7 + RTNLGRP_IPV4_RULE = 0x8 + RTNLGRP_IPV6_IFADDR = 0x9 + RTNLGRP_IPV6_MROUTE = 0xa + RTNLGRP_IPV6_ROUTE = 0xb + RTNLGRP_IPV6_IFINFO = 0xc + RTNLGRP_IPV6_PREFIX = 0x12 + RTNLGRP_IPV6_RULE = 0x13 + RTNLGRP_ND_USEROPT = 0x14 + SizeofNlMsghdr = 0x10 + SizeofNlMsgerr = 0x14 + SizeofRtGenmsg = 0x1 + SizeofNlAttr = 0x4 + SizeofRtAttr = 0x4 + SizeofIfInfomsg = 0x10 + SizeofIfAddrmsg = 0x8 + SizeofRtMsg = 0xc + SizeofRtNexthop = 0x8 ) type NlMsghdr struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go index da70faa82..4b86fb2b3 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go @@ -103,6 +103,15 @@ const ( PathMax = 0x400 ) +const ( + FADV_NORMAL = 0x0 + FADV_RANDOM = 0x1 + FADV_SEQUENTIAL = 0x2 + FADV_WILLNEED = 0x3 + FADV_DONTNEED = 0x4 + FADV_NOREUSE = 0x5 +) + type RawSockaddrInet4 struct { Len uint8 Family uint8 diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go index 0963ab8c4..9048a509d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go @@ -107,6 +107,15 @@ const ( PathMax = 0x400 ) +const ( + FADV_NORMAL = 0x0 + FADV_RANDOM = 0x1 + FADV_SEQUENTIAL = 0x2 + FADV_WILLNEED = 0x3 + FADV_DONTNEED = 0x4 + FADV_NOREUSE = 0x5 +) + type RawSockaddrInet4 struct { Len uint8 Family uint8 diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go index 211f64193..00525e7b0 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go @@ -108,6 +108,15 @@ const ( PathMax = 0x400 ) +const ( + FADV_NORMAL = 0x0 + FADV_RANDOM = 0x1 + FADV_SEQUENTIAL = 0x2 + FADV_WILLNEED = 0x3 + FADV_DONTNEED = 0x4 + FADV_NOREUSE = 0x5 +) + type RawSockaddrInet4 struct { Len uint8 Family uint8 diff --git a/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go index d44545248..2248598d0 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go @@ -93,40 +93,40 @@ const ( ) type Stat_t struct { - Dev uint64 - Ino uint64 - Mode uint32 - Nlink uint32 - Uid uint32 - Gid uint32 - Rdev uint64 - Size int64 - Atim Timespec - Mtim Timespec - Ctim Timespec - Blksize int32 - Pad_cgo_0 [4]byte - Blocks int64 - Fstype [16]int8 + Dev uint64 + Ino uint64 + Mode uint32 + Nlink uint32 + Uid uint32 + Gid uint32 + Rdev uint64 + Size int64 + Atim Timespec + Mtim Timespec + Ctim Timespec + Blksize int32 + _ [4]byte + Blocks int64 + Fstype [16]int8 } type Flock_t struct { - Type int16 - Whence int16 - Pad_cgo_0 [4]byte - Start int64 - Len int64 - Sysid int32 - Pid int32 - Pad [4]int64 + Type int16 + Whence int16 + _ [4]byte + Start int64 + Len int64 + Sysid int32 + Pid int32 + Pad [4]int64 } type Dirent struct { - Ino uint64 - Off int64 - Reclen uint16 - Name [1]int8 - Pad_cgo_0 [5]byte + Ino uint64 + Off int64 + Reclen uint16 + Name [1]int8 + _ [5]byte } type _Fsblkcnt_t uint64 @@ -213,13 +213,13 @@ type IPv6Mreq struct { type Msghdr struct { Name *byte Namelen uint32 - Pad_cgo_0 [4]byte + _ [4]byte Iov *Iovec Iovlen int32 - Pad_cgo_1 [4]byte + _ [4]byte Accrights *int8 Accrightslen int32 - Pad_cgo_2 [4]byte + _ [4]byte } type Cmsghdr struct { @@ -271,11 +271,11 @@ type Utsname struct { } type Ustat_t struct { - Tfree int64 - Tinode uint64 - Fname [6]int8 - Fpack [6]int8 - Pad_cgo_0 [4]byte + Tfree int64 + Tinode uint64 + Fname [6]int8 + Fpack [6]int8 + _ [4]byte } const ( @@ -295,21 +295,21 @@ const ( ) type IfMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Data IfData + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Data IfData } type IfData struct { Type uint8 Addrlen uint8 Hdrlen uint8 - Pad_cgo_0 [1]byte + _ [1]byte Mtu uint32 Metric uint32 Baudrate uint32 @@ -328,30 +328,30 @@ type IfData struct { } type IfaMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Addrs int32 - Flags int32 - Index uint16 - Pad_cgo_0 [2]byte - Metric int32 + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + _ [2]byte + Metric int32 } type RtMsghdr struct { - Msglen uint16 - Version uint8 - Type uint8 - Index uint16 - Pad_cgo_0 [2]byte - Flags int32 - Addrs int32 - Pid int32 - Seq int32 - Errno int32 - Use int32 - Inits uint32 - Rmx RtMetrics + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + _ [2]byte + Flags int32 + Addrs int32 + Pid int32 + Seq int32 + Errno int32 + Use int32 + Inits uint32 + Rmx RtMetrics } type RtMetrics struct { @@ -388,9 +388,9 @@ type BpfStat struct { } type BpfProgram struct { - Len uint32 - Pad_cgo_0 [4]byte - Insns *BpfInsn + Len uint32 + _ [4]byte + Insns *BpfInsn } type BpfInsn struct { @@ -406,30 +406,30 @@ type BpfTimeval struct { } type BpfHdr struct { - Tstamp BpfTimeval - Caplen uint32 - Datalen uint32 - Hdrlen uint16 - Pad_cgo_0 [2]byte + Tstamp BpfTimeval + Caplen uint32 + Datalen uint32 + Hdrlen uint16 + _ [2]byte } type Termios struct { - Iflag uint32 - Oflag uint32 - Cflag uint32 - Lflag uint32 - Cc [19]uint8 - Pad_cgo_0 [1]byte + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [19]uint8 + _ [1]byte } type Termio struct { - Iflag uint16 - Oflag uint16 - Cflag uint16 - Lflag uint16 - Line int8 - Cc [8]uint8 - Pad_cgo_0 [1]byte + Iflag uint16 + Oflag uint16 + Cflag uint16 + Lflag uint16 + Line int8 + Cc [8]uint8 + _ [1]byte } type Winsize struct { diff --git a/vendor/golang.org/x/sys/windows/syscall.go b/vendor/golang.org/x/sys/windows/syscall.go index b07bc2305..af828a91b 100644 --- a/vendor/golang.org/x/sys/windows/syscall.go +++ b/vendor/golang.org/x/sys/windows/syscall.go @@ -11,11 +11,14 @@ // system, set $GOOS and $GOARCH to the desired system. For example, if // you want to view documentation for freebsd/arm on linux/amd64, set $GOOS // to freebsd and $GOARCH to arm. +// // The primary use of this package is inside other packages that provide a more // portable interface to the system, such as "os", "time" and "net". Use // those packages rather than this one if you can. +// // For details of the functions and data types in this package consult // the manuals for the appropriate operating system. +// // These calls return err == nil to indicate success; otherwise // err represents an operating system error describing the failure and // holds a value of type syscall.Errno. diff --git a/vendor/golang.org/x/tools/CONTRIBUTING.md b/vendor/golang.org/x/tools/CONTRIBUTING.md index 88dff59bc..d0485e887 100644 --- a/vendor/golang.org/x/tools/CONTRIBUTING.md +++ b/vendor/golang.org/x/tools/CONTRIBUTING.md @@ -4,16 +4,15 @@ Go is an open source project. It is the work of hundreds of contributors. We appreciate your help! - ## Filing issues When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions: -1. What version of Go are you using (`go version`)? -2. What operating system and processor architecture are you using? -3. What did you do? -4. What did you expect to see? -5. What did you see instead? +1. What version of Go are you using (`go version`)? +2. What operating system and processor architecture are you using? +3. What did you do? +4. What did you expect to see? +5. What did you see instead? General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker. The gophers there will answer or ask you to file an issue if you've tripped over a bug. @@ -23,9 +22,5 @@ The gophers there will answer or ask you to file an issue if you've tripped over Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) before sending patches. -**We do not accept GitHub pull requests** -(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review). - Unless otherwise noted, the Go source files are distributed under the BSD-style license found in the LICENSE file. - diff --git a/vendor/golang.org/x/tools/cmd/godoc/main.go b/vendor/golang.org/x/tools/cmd/godoc/main.go index 901e992a1..aa2996a44 100644 --- a/vendor/golang.org/x/tools/cmd/godoc/main.go +++ b/vendor/golang.org/x/tools/cmd/godoc/main.go @@ -72,6 +72,7 @@ var ( // layout control html = flag.Bool("html", false, "print HTML in command-line mode") srcMode = flag.Bool("src", false, "print (exported) source in command-line mode") + allMode = flag.Bool("all", false, "include unexported identifiers in command-line mode") urlFlag = flag.String("url", "", "print HTML for named URL") // command-line searches @@ -253,6 +254,7 @@ func main() { pres.DeclLinks = *declLinks pres.SrcMode = *srcMode pres.HTMLMode = *html + pres.AllMode = *allMode if *notesRx != "" { pres.NotesRx = regexp.MustCompile(*notesRx) } diff --git a/vendor/golang.org/x/tools/cmd/guru/testdata/src/referrers/main.golden b/vendor/golang.org/x/tools/cmd/guru/testdata/src/referrers/main.golden index 230e95e73..dc97f6ac0 100644 --- a/vendor/golang.org/x/tools/cmd/guru/testdata/src/referrers/main.golden +++ b/vendor/golang.org/x/tools/cmd/guru/testdata/src/referrers/main.golden @@ -56,5 +56,5 @@ references to field f int -------- @referrers ref-type-U -------- references to type U int -open testdata/src/referrers/nosuchfile.y: no such file or directory (+ 1 more refs in this file) +open nosuchfile.y: no such file or directory (+ 1 more refs in this file) diff --git a/vendor/golang.org/x/tools/godoc/cmdline.go b/vendor/golang.org/x/tools/godoc/cmdline.go index 7c5368134..b531b4df7 100644 --- a/vendor/golang.org/x/tools/godoc/cmdline.go +++ b/vendor/golang.org/x/tools/godoc/cmdline.go @@ -48,6 +48,9 @@ func CommandLine(w io.Writer, fs vfs.NameSpace, pres *Presentation, args []strin // the fake built-in package contains unexported identifiers mode = NoFiltering | NoTypeAssoc } + if pres.AllMode { + mode |= NoFiltering + } if srcMode { // only filter exports if we don't have explicit command-line filter arguments if len(args) > 1 { diff --git a/vendor/golang.org/x/tools/godoc/cmdline_test.go b/vendor/golang.org/x/tools/godoc/cmdline_test.go index 602f2bbab..8c9ce22ee 100644 --- a/vendor/golang.org/x/tools/godoc/cmdline_test.go +++ b/vendor/golang.org/x/tools/godoc/cmdline_test.go @@ -172,6 +172,10 @@ func First() { // Second function is second. func Second() { } + +// unexported function is third. +func unexported() { +} `, "src/gen/gen.go": `// Package gen package gen @@ -220,6 +224,7 @@ package main for _, tc := range []struct { desc string args []string + all bool exp string err bool }{ @@ -253,6 +258,18 @@ package main args: []string{"src/foo", "Second"}, exp: "// Second function is second.\nfunc Second() {\n}", }, + { + desc: "package w. unexported filter", + args: []string{"foo", "unexported"}, + all: true, + exp: "PACKAGE \nfunc unexported()\n unexported function is third.\n", + }, + { + desc: "package w. unexported filter", + args: []string{"foo", "unexported"}, + all: false, + exp: "PACKAGE ", + }, { desc: "package w. //line comments", args: []string{"gen", "F"}, @@ -284,11 +301,12 @@ package main exp: "", }, } { + p.AllMode = tc.all w := new(bytes.Buffer) err := CommandLine(w, fs, p, tc.args) if got, want := w.String(), tc.exp; got != want || tc.err == (err == nil) { - t.Errorf("%s: CommandLine(%v) = %q (%v); want %q (%v)", - tc.desc, tc.args, got, err, want, tc.err) + t.Errorf("%s: CommandLine(%v), All(%v) = %q (%v); want %q (%v)", + tc.desc, tc.args, tc.all, got, err, want, tc.err) } } } diff --git a/vendor/golang.org/x/tools/godoc/dirtrees.go b/vendor/golang.org/x/tools/godoc/dirtrees.go index 2b14a41e3..fed6ee1b1 100644 --- a/vendor/golang.org/x/tools/godoc/dirtrees.go +++ b/vendor/golang.org/x/tools/godoc/dirtrees.go @@ -13,6 +13,7 @@ import ( "log" "os" pathpkg "path" + "runtime" "strings" ) @@ -55,7 +56,13 @@ type treeBuilder struct { // ioGate is a semaphore controlling VFS activity (ReadDir, parseFile, etc). // Send before an operation and receive after. -var ioGate = make(chan bool, 20) +var ioGate = make(chan struct{}, 20) + +// workGate controls the number of concurrent workers. Too many concurrent +// workers and performance degrades and the race detector gets overwhelmed. If +// we cannot check out a concurrent worker, work is performed by the main thread +// instead of spinning up another goroutine. +var workGate = make(chan struct{}, runtime.NumCPU()*4) func (b *treeBuilder) newDirTree(fset *token.FileSet, path, name string, depth int) *Directory { if name == testdataDirName { @@ -88,7 +95,7 @@ func (b *treeBuilder) newDirTree(fset *token.FileSet, path, name string, depth i } } - ioGate <- true + ioGate <- struct{}{} list, err := b.c.fs.ReadDir(path) <-ioGate if err != nil { @@ -101,23 +108,34 @@ func (b *treeBuilder) newDirTree(fset *token.FileSet, path, name string, depth i // determine number of subdirectories and if there are package files var dirchs []chan *Directory + var dirs []*Directory for _, d := range list { filename := pathpkg.Join(path, d.Name()) switch { case isPkgDir(d): - ch := make(chan *Directory, 1) - dirchs = append(dirchs, ch) name := d.Name() - go func() { - ch <- b.newDirTree(fset, filename, name, depth+1) - }() + select { + case workGate <- struct{}{}: + ch := make(chan *Directory, 1) + dirchs = append(dirchs, ch) + go func() { + ch <- b.newDirTree(fset, filename, name, depth+1) + <-workGate + }() + default: + // no free workers, do work synchronously + dir := b.newDirTree(fset, filename, name, depth+1) + if dir != nil { + dirs = append(dirs, dir) + } + } case !haveSummary && isPkgFile(d): // looks like a package file, but may just be a file ending in ".go"; // don't just count it yet (otherwise we may end up with hasPkgFiles even // though the directory doesn't contain any real package files - was bug) // no "optimal" package synopsis yet; continue to collect synopses - ioGate <- true + ioGate <- struct{}{} const flags = parser.ParseComments | parser.PackageClauseOnly file, err := b.c.parseFile(fset, filename, flags) <-ioGate @@ -149,7 +167,6 @@ func (b *treeBuilder) newDirTree(fset *token.FileSet, path, name string, depth i } // create subdirectory tree - var dirs []*Directory for _, ch := range dirchs { if d := <-ch; d != nil { dirs = append(dirs, d) diff --git a/vendor/golang.org/x/tools/godoc/pres.go b/vendor/golang.org/x/tools/godoc/pres.go index 855117764..b8205e24c 100644 --- a/vendor/golang.org/x/tools/godoc/pres.go +++ b/vendor/golang.org/x/tools/godoc/pres.go @@ -53,6 +53,8 @@ type Presentation struct { SrcMode bool // HTMLMode outputs HTML instead of plain text in command-line mode. HTMLMode bool + // AllMode includes unexported identifiers in the output in command-line mode. + AllMode bool // NotesRx optionally specifies a regexp to match // notes to render in the output. diff --git a/vendor/golang.org/x/tools/godoc/static/godoc.html b/vendor/golang.org/x/tools/godoc/static/godoc.html index fb26901c8..6c7889f05 100644 --- a/vendor/golang.org/x/tools/godoc/static/godoc.html +++ b/vendor/golang.org/x/tools/godoc/static/godoc.html @@ -14,7 +14,16 @@ <link rel="search" type="application/opensearchdescription+xml" title="godoc" href="/opensearch.xml" /> {{end}} <link rel="stylesheet" href="/lib/godoc/jquery.treeview.css"> -<script type="text/javascript">window.initFuncs = [];</script> +<script>window.initFuncs = [];</script> +<script src="/lib/godoc/jquery.js" defer></script> +<script src="/lib/godoc/jquery.treeview.js" defer></script> +<script src="/lib/godoc/jquery.treeview.edit.js" defer></script> + +{{if .Playground}} +<script src="/lib/godoc/playground.js" defer></script> +{{end}} +{{with .Version}}<script>var goVersion = {{printf "%q" .}};</script>{{end}} +<script src="/lib/godoc/godocs.js" defer></script> </head> <body> @@ -103,18 +112,6 @@ and code is licensed under a <a href="/LICENSE">BSD license</a>.<br> </div><!-- .container --> </div><!-- #page --> - -<!-- TODO(adonovan): load these from <head> using "defer" attribute? --> -<script type="text/javascript" src="/lib/godoc/jquery.js"></script> -<script type="text/javascript" src="/lib/godoc/jquery.treeview.js"></script> -<script type="text/javascript" src="/lib/godoc/jquery.treeview.edit.js"></script> - -{{if .Playground}} -<script type="text/javascript" src="/lib/godoc/playground.js"></script> -{{end}} -{{with .Version}}<script>var goVersion = {{printf "%q" .}};</script>{{end}} -<script type="text/javascript" src="/lib/godoc/godocs.js"></script> - </body> </html> diff --git a/vendor/golang.org/x/tools/godoc/static/package.html b/vendor/golang.org/x/tools/godoc/static/package.html index 9c81890af..e11b886d0 100644 --- a/vendor/golang.org/x/tools/godoc/static/package.html +++ b/vendor/golang.org/x/tools/godoc/static/package.html @@ -319,6 +319,7 @@ <li><a href="//godoc.org/golang.org/x/net">net</a> — additional networking packages.</li> <li><a href="//godoc.org/golang.org/x/sys">sys</a> — packages for making system calls.</li> <li><a href="//godoc.org/golang.org/x/text">text</a> — packages for working with text.</li> + <li><a href="//godoc.org/golang.org/x/time">time</a> — additional time packages.</li> <li><a href="//godoc.org/golang.org/x/tools">tools</a> — godoc, goimports, gorename, and other tools.</li> <li><a href="//godoc.org/golang.org/x/tour">tour</a> — <a href="//tour.golang.org">tour.golang.org</a>'s implementation.</li> <li><a href="//godoc.org/golang.org/x/exp">exp</a> — experimental and deprecated packages (handle with care; may change without warning).</li> diff --git a/vendor/golang.org/x/tools/godoc/static/static.go b/vendor/golang.org/x/tools/godoc/static/static.go index d450f472b..19d6db2d9 100644 --- a/vendor/golang.org/x/tools/godoc/static/static.go +++ b/vendor/golang.org/x/tools/godoc/static/static.go @@ -283,7 +283,7 @@ var Files = map[string]string{ "analysis/ident-field.png": "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x03\xd2\x00\x00\x00\xde\b\x03\x00\x00\x00\xe6g\xc8\n\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x02\xfdPLTE\x00\x01\x00\x02\x05\x01\n\x03\x01\x05\b\x03\f\x0e\v\f\x10\x1c\x0e\x11\x14\x10\x12\x0f\r\x15$\x16\x17\x14\x1c\x1b\x15\x1b\x1d\x1a\x1f\x1f\x19\x13#A!# $$\x1d#$\"$%#&'%\x19(G((!'(&+)\x1e\x14+N()'++$*,)/-\"*.0-.,02/63(241685<9-5:=:;9=?=CA5AB@CEBKH<MH7HIG\x00f\x00\x00i\x01JLI\x00j\x02SN=MOL\x05m\x05PRO\fo\t4U\x98XSBTUS\x0fq\v\fr\x177Y\xa3WYV,`\xae7]\xad\x15w\x1c\\^[c^L9a\xab\x19y\x1e_`^;c\xad=d\xae)z!ac`De\xa3?f\xb0)|*Bh\xb3egdghfLi\xafDl\xb0qjSikh/\x82/Ho\xb3/\x859Jq\xb6mol;\x86:Ut\xb4Xv\xb6?\x8a>|u]tvsB\x8c@@\x8dG\\z\xbby{x]~\xb7e|\xb8K\x90J\x85}e_\x80\xba}\u007f|O\x93Nb\x83\xbdN\x95Ud\x85\xbf\x81\x83\x80W\x95Vl\x87\xbc\x90\x86hZ\x98Yo\x89\xbf\x87\x89\x86]\x9c\\\\\x9dds\x8dÕ\x8cn\x8b\x8d\x8az\x8e\xbfe\x9ef\x8d\x8f\x8c|\x90\xc1\x9b\x91s\x90\x92\x8fi\xa2i~\x93\xc4x\x95Ā\x94œ\x94\x91\x9f\x95w{\x98\xc7s\xa4lq\xa5s\x95\x97\x94\x82\x9aė\x99\x96\x83\x9cƙ\x9b\x98u\xaaw\xa6\x9b}\x87\x9f\xc9~\xaay\x9c\x9e\x9b\x89\xa1ˀ\xad|\x9f\xa1\x9e\x8f\xa2ǫ\xa1\x82\xa1\xa3\xa0\xa2\xa4\xa1\x92\xa5ʂ\xb1\x85\xa5\xa7\xa4\x8a\xb2\x87\xb4\xa7\x83\x8b\xb3\x89\x96\xa9Χ\xa9\xa6\x98\xabю\xb6\x8c\xaa\xac\xa9\x9e\xad͍\xb8\x93\xba\xad\x88\xad\xaf\xac\x95\xb9\x95\xa1\xb0Я\xb1\xae\xa3\xb2Ә\xbc\x98\xa5\xb5ճ\xb5\xb2\x9b\xbf\x9bµ\x90\xab\xb7ѵ\xb7\xb4\xa3\xbf\x9d\xa2\xc0\xa4\xad\xb9ӷ\xb9\xb6\xb9\xbb\xb8\xb0\xbc֦Ũ\xbb\xbd\xba\xb3\xbeٽ\xbf\xbc\xa8ǫ\xb7\xbfԯƫ\xbf\xc1\xbd\xce\xc0\x9b\xb9\xc1ֲɮ\xc1ÿ\xbb\xc3\xd8\xc2\xc4\xc1\xbd\xc4ڲ̷\xc4\xc6\xc3\xc0\xc8ݻ\xca\xde\xc7\xc9ƻκ\xd9ɝ\xc6\xca\xd9\xc0\xcc\xda\xc7\xcb\xdb\xca\xccɿҾ\xc9\xcd\xdd\xd7ϡ\xcd\xcf\xcc\xc4\xd0\xde\xc8\xd3\xc1\xcc\xd0\xe0\xcf\xd1\xce\xe1ѥ\xd2\xd2\xdd\xc9\xd7\xcb\xd2\xd4\xd1\xcd\xd6\xde\xcc\xda\xce\xe6֪\xcf\xd8\xe0\xd5\xd8\xd4\xd2\xda\xe2\xd8\xda\xd6\xd8\xd9\xe3\xd5\xdc\xd1\xd3\xdc\xe4\xda\xdc\xd9\xe6ݯ\xd8\xdd\xe0\xd5\xdf\xda\xdc\xde\xdb\xdc\xdd\xe7\xda\xdf\xe2\xd7\xe1\xdc\xe0\xde\xe2\xde\xe0\xdd\xf0\xe0\xb3\xdf\xe1\xde\xdc\xe2\xe4\xde\xe3\xe6\xe1\xe3\xdf\xe3\xe5\xe2\xe1\xe6\xe9\xe8\xe5\xea\xe5\xe7\xe4\xe4\xe9\xeb\xe7\xe9\xe6\xf1\xf3\xf0\xfa\xfc\xf9\xfe\xff\xfcŃ\x89%\x00\x00 \x00IDATx^\xed\x9d\x0fX\x14\u05fd\xf7/\u05fc\xf5m\xea\x9d(o\xb9o/)\x04S\xac\xb6Y\xd9摖p\xcd<f\t\xe8\x8d\x18\xb9\x8a \x1aR\xa4&J\xa3VL\x8c\x18b\x1e5ָ\xc1\x10,i@\xafJ\xb34\x06\xb4\xa4P\xe3\x1fb\xc0\x98\bj0&$/)i\xc0\x98\r\x1a\x93\x9a?\xf8\xc8B\xe0\xb4<\xef9gfg\xce\xcc\xce\xec,\b;\xec\xf2\xfb<\x0f\xbbgg\u007fs\xe6\xec\xd9\xf3\xdd\xf3g\x86\xf9\xfeK\xff\xa0A\x00\x00\x8c8\xfe\xc5H\xb8\xfa\x18e\r\x00\x80\xff\x01I\x03@P\x01\x92\x06\x80\xa0\x02$\r\x00A\x05H\x1a\x00\x82\n\x904\x00\x04\x15 i\x00\x18Zz\x8d\x02\x86\x17\x904\x00\f!\xce\xf4\x89\xdc,\xa3\xa0a%\xd8%]6\xcdi\x14b&\x1d\xd3ʌB\x02\x91Q\\\xebS\xa6\xd8+?4\n\x1aV̓tӾ\xa2\x92cb\xfa\xb4\xdd\xe15\xf6\x9b\x8ds\x13s\xfb\xbc\x86h\xf3\x18\xb7\xc6(d\xa8h]\x95\x94\x92w2\xe5K\xf5\xf6Ol\xfc\"\xadx\x81\xc7Ư\xf3\xd8V\xc4a\xa2f\x1c\xd7\bgh\t\xe5\xa6\xf8\x1a\xeb#$\xb35h\r~,\xf0\x12%\x1c\xd8\x1bC_\xeb\xfbyL\xf2\xaaw\x8c\xe2|D\xabև\x86\x06n\x9fQ\xc8pc\x96\xa4]\x95\xf6\xc3-\xc7\xed\xcd\xf4\xc5\xe5\x82C\xc5^\xa3\x1fJ\xa9\xc8O\xba\xe65D\x93\xcd㋌B\x86\x8a\x13I\xbf\xaa\xa8\xce\xe2\xf9\x0f\xd4o\xf4\x9d\xd9h\xd3\xdaA\xc41a\xb3zӕ\"n]U\xd14\xaeJ+^\xe6pz\x98ϱީ\x12\u007f\x11HfN\xe4|\x8c+\xba\xe2-\x9c\x1e\xd8\v\xc3P\xeb\xd7\xf6\xf3{O\xeeϾ\xf3\xa4Q\xa07N\xbe+%5j}h\xa8\xe5j\x8cB\x86\x1b\xb3$]Y\x80\x87fN{\x13}\xe1\xa8l\xf7*\xe9\xaf\xf8r\xd4\xd7\xe5-B\x9b\x96\xd0e\xde\x03:\xe2:\xbc\a\xf8\xccWɹ=\buexJ\x1a\xa1Ro\x92F+\xc2\xda՛Nӟ\xfa\xb8\xc9\x1a\xd1,k\xc2|\x8f\xf5\xca\xedsĄ\x90Y\x15w\xda[\xb4x`]\x86\xa5\xd6[\xf9\x13\xf8\xd71'\xc3(\xce\x1b\xd9k\xe5\xb4F\xad\x0f\t\xb5\xdca\xa3\x90\xe1\xc6$I;\xedo\x92'\xa138]\xe4rz\x95\xf4y\xfe\x88\xb7\xb7uI\x9f\xd8\xe9=\xe0\xb4Q\xe3\xf5\x99¤\xcf\xc8S9\xff\x91\xe7{\xde%\xdd91]\xbdIP\xd6fΠ\xf4\x8c\xa4\rc\xbd\x123\xa4\x92\x1e\x96Z\xa7\x92\xc6\xd5;\x88\x1fv\x89,F\xd2\x1a\xb5>$\x8c^I\x1f.\xe8\x96\xd2W\n\x9a\x91\x17I\xf7\xcc\xe5)O#\xb4\x85\xe7\xabŹ\xe9\x16\xdeV\xf1tFҪ\x8b4\xe6\xfcڹ\xb6\x94܋\xaa=]\x11Rw\xd1<'*t\xe2\f\xe5\x9a\xcd\xe6Ɏ&\xae\xc91\xf9)\x9cn\\\x95f\x9b\x9b\x9bF\xa6\xeb}\u007f\xcaN\xcax\x1a7\x9d\xf7m<\xbf\xe3|~Z\xe2\xaao\xab\xf1\xf1KQ)O\x8e\xaf\x19\x8026\xd1<\xbf(\xc7}u_EvRV\x05\x9d\xfa_\xccKM^+\f\xbc\xa5ݐ\xaa\xbc+\xc2]H\x89\xa0\xacy\xd1\xf4E\xf1\xb4\xf0\xc9K\x88H\xae̙\x18\x1a}w\x03\xdd\xe8\x9c71rN\xba,iu,\xea\\6%\"\xeep\xf4>\x94ɍ/\x96\xa7\xbfr@͌\xe8Ш\x19x7\a'\x10\x83T\x9268\xb0\x1c\xd00\x81\xe3V4ϛ\x14>\x83|\xa9\xeeZWn\x95\x90k\x9d\xa9>\xfcm\x96oJM\xce=OC\xb4\xbeMA\xd2y\xa9$\xcd\xd4dWᢤ\x9c3\xa9ul\xd3P\x04H_\xec\x11\xa1\x15\xf1\xd9b\x86\x9e\xb5\xae\xf9\x81\x94\x9f⩘\xf0\x18\xd2\\t>\x1b\"u7Z%]\xe6h\xdae/>Dk\xd5Q\x89\xbcI\x1a}\xd0X͗66\xe2^\xf0b\xa3\xadT\x9c\x9b\xb6V\xdb\xf8\x94\xd2?$璈\x93I\xd9{O\x94\xe2ѹ\x92\xe3\xd2\f\xb3*\"\xe6\xb1\xca5\xdc\x06\xc5\xdb\xcey\xdc\x14\xee6n\x0e\x1e\x81\xbdsg\xfe+'*\xe6\xf2\xdf\xe2͛\xf8mu\xe5)Y}\xa8\xa7\xba:-\xe3\x9eԧ\xf3\xee\xfc\xb4\xab1\xf9\xb9/ї\xcf%7vi\a\xf4\xb0\aϷ\xed\xa8\xdba\xcbǩ\xf3\xc9\x19\xfb\x8f\xac⩤\xa5\xdd\xd4\xe5=\xe4\xd1\nNs\x0eW\xd32\x8e.ᤏ\xcftl\x8e\x8a\xe9%\xdaK\xaf*\xb9{|-\xde\xd8\x1c1\xb9\xa8l:\x17\xa6\x1b{yR\xd4c\x8eL\x8e{\n9kB\xd7H\xd3_9\xa0\x96\x9b\xb7\xab\xd2\x1e\xc5u\xa3\xceC5\x93\xe3jjj\x9a\xc4\xcc\\\xae}T\xd2F\a\x96\x03\\%\xc5ѓ#\xa2\x97\xcc\xe3\xc8R\xaf\xbb֕[%\xe4Zg\xaa\x8f|\x9bi\xa5\xa5iI\xadH\xe7\xdbl\xe5\xeb\xba>*Ŀ\xab\x88\xad\xc9ki\xc9\xe5uX\xcd\x15l\xd3`\x03\xe4/\xb6\xebLcFNcc\xa3{\x14\xe5Y\xeb\x9a\x1fH\xf1)\xd2\xc3V8V\x84\xcd\xd3\xfdl\xddΪ\xdb#\xafg\xb84$\x98$\xe9\x12{qC{Sq\t\xd6tSQ\xa7wI\xb3\x03o\x1b\xf9N\x85\x81\xac-\x19\xff\x8e\xe7\xa7\xe0TO\xda*\xdc7\xf6T\u007f\xa5\xda\xcd\xc1\xb5\b\tW\xf4\f\x17\xf9\x1e\xd4S\xb8}\xa1\\(]\xa0\xacH!b.Oƍ\xe0U~?N\x9e#\xdd1\x1e\xaa\xf1\x0f]C}d]nS\x1e~\xc8#]\xb1f\xc0'\xccԠ\x8ev('\xf8:\x84r2\xf0O@_\x96M\xb9\x9b\xaa\xbc\xed\xdc.\xa4\xe44\xed6瑤\x83#KM\xb5\xdc\xf3\xa4\xfc\xa4\xb5\xdcFNz\xc6M\xc2\xc9ޘ0\xdd\xd8y\x91dD\xb2\x84#]J\x18Y~\xa6ce&\xe0\xa9(ҿl\x8e\xa4\xc7c\x06\xde\x02\xa7}80\x13\x80s\xe0\xa6_\x11\xe7QR\xad+\xb62H\xb5\xce֯-\xed\x1aQh\xb6\u07b7\xd9J\xbb\xd8|\xf2\x83\xc8\xd4d>i\x03h\x1b\x964\xdb4\x98\x00\xe6\x8bU\x0e\xbc5j]\xef\x03I\xc9}t\f#<j~\xb6Y\xb8꼟\xba\xf1\a&I\xdaQ@*\xa3\xb3\xa8\x16u\x164\xf5\xf6\xf6~X\xec\xed\x92\x1bmI结uZkR\x982w\xe3rpoj\xbcݱ$4\x9a\x9b\x18\xb6\x04\v\xfd\xd3Դm\x15\x1f\xf4ᦄ\xf2\xd2z\xbeŤҁt\x96\xedS1\xf8db\x17\xeaJ:\xa9\x17\xd0c\x93;\x95M\xc29\xabE\x1b\xd15\xda\xd6\xd0\x0e\x9br7UyۅF\xc4p\x9a\xdbp\xd81-\x9c\x94\xfe\xdeI\xaenL4\x99\xf9u<5cR\x04w\x1b\xee\x839;\t[\x11\xa6\x1b\x1bN\xcf\"5\xa9$\xcd\x04\xb4O\x9c\x94i\u007f\x13\t\x83OF\xd2\x1bjkk7\x10I\x1b\x1e\x98\r@1aRwU\xc6H:LщQ\x98Zg\xeb\xd7VH\x1e\xcb\xf9\xaft\xbe\xcdV\xfe\x0f\xe7^\xcdN\xfc\x04\xb15ٗT*\xbc\xa7\x944S\xd5\xcc\x17\xeb!iu\xad\xeb} )\x99~\x1b}\x9a\xa2\x0e\x90\xf8p\x9f}ʨ\xed\xa5\xab\x84\x9fȪ2\xd4bw\xa3\u007fu\x82\xb6\xa4\xa5d9ߣ\xb9\xdba\xf7\xd8j3\xe79oB\xe8\xb1(;\x9e\xd5m\x8e\"c\xd6k\x15k3\xf8\xb9{\xfbH\xc7!@G\xf4Y\xee\x99\x17\xfa6\xf9\b:2\x97\xfc\xd8k\a\x88s\xe9\x1e\xdcA?H\xdfA\xb9ٸ\xa3h$)ZHf7Uyk\xb9CH\t\x9d\xd2^\x1eO\xe4\x13#\xf6\x9b\xb8\x8b\xac\x9d\x18\xbdlW\xcdtܮ\x8e\tgJ\xe4\xe51u\xac\xd8\x05]QI\x9a\xc9\f]\xb6ϙ\xc2E=F\x8f\xa7\xb5<fx`63\x14s\xbbT\xf8\xc3\xf2\x88\x96\xd9*\xc1\xd6:S\xbf\xf4\xdbD\x8d\xfc\xbb:\xdf&\x9dK\v?\x91rM^\x14\xdaE\x97J\xd2\xec7$\u007f\xb1*I{ֺ\xde\a\x92\x92\xd3\xee\xa6O3\xa6\xa9\x02Xj\xb8Z\xcd\xed~\xc4$I\x1f/\xa2\xbdr%\x1e\xa6t81\xa7\x8b\x9c\xfa\x8aVKz\x87J\xd2'\xf8\xf75w\xeb\f\x13\xafx\xa8\xe44/\xc5pѵW\xa2\xf6s\x85dbV\x9dXA~\xe2ߥ|A\"\x98F\xb0-\x17\xe5n#\t\xed\x80\xc2D\xfa\xba\x9a\xff\x12m\x12V\xd9\xd2\xf2\xd17B/\x9doS\xee\xa6*\xef\x9aP\xf5\xd0TPV\x04)\xfd\xbcI\xc7)\xb8S\x9b2\x8d\x14u\x0eVV\a\x95*b\x96\xc7T\xb1\xbdB/}Z\x964\xedX\x99̎\x915\xac+χӌ\xa8\xa4\v>TH\xda\xf0\xc0L\x00\xf3\xa3\xc0Ժb\xab\x8c\\\xebl\xfd\xdah\xddV\xf0\xd7t\xbeMay,\x99|\xe7rM\x8a\xbd\xf4\a\xb2\xa4w\xa8\xaa\x9a\xf9bţ\xed\x17\xc7\x05\x9e\xb5\xae\xf7\x81\xa4d\xfa$\xfa4)]\x15\xc02zW\xbc;\xe8I\xac+\x05\xee\xcb\xc7|\x9dK'\xe1\xf1Y߯T\x92\xeeJ\xc9!?\xec۶\xa9\xf7\x9b3Y\x18\xcewN\x8c#M(s\x89:\xa0=R8;YJ&\xbex껑\xe8\x8dN\x92\v\xf7\x92GF\xd2o%~\x96\xf8\x16Ih\a\b\xe7\xa5\xfbr\xd2ȸ\x9a\x04T\x93,\xb3\xd3\xf0\x8c\xf0\xa3D\x9br7ey{\xa7\xcc@*\x04eM\\Ұ\x06\xcf\xdcJȖ\x15\xb8S\x8b&\x8d\xa87\x86\x8c\xfe\xa6E\xe3v\xd7\xfc\x830\xdd\xd89Q\xa4aΣ\n\f\xc7\xea\xed\xbd\x9d\xc42\x01k\x84\x19a\\&}\x8c\xc3\xdf\x00y\x8f\x91\xb4ၙ\x00e\x03w\u05fan\xb3w\u05faB\xd2s\xbbpŤ\xe5\xa8k\xa7e\x9d0\x8c\x17$\x9d\xb2\xad\xb5\x94\xadɵs\xb1l\xfb\xf2\xa9\xa4\xe5\xa6\xc1\x040_,~Ĺ\u007f)\xbc\xa7U\xebz\x1fHJ:\xe8X\xfdya\xba\f\x92Vs\xac\xe0X\xfb\xe9\xe2]\xdd\xf4E/\xe9\xa5u/?\x10V\xbc\xcfбӃ){K\xb3y\xdb\xfe\xd6\xcf\x1am\x1b\xcf\xf4\xbd\xb3\xd1FV\xc2O&.\xaa\xa8\x13\x16I\x144\x8f\x17\u05f8\xab~0\xe5)G\xa6\xfee\x8e\xa5|R\xe9\xabG6\xf1d\xae\\xg\xde+8Y\x8d\xbe}\x8b\xae\x91~\"\x84\xf4\xa5\xaeJ\x15.I\xd5\x0e\xa8Kzp\xff\x91U\xb638\x99\xc7\x17\xbeZȓ\xf5\xb4֤\xd4\xd2\x1dɤ\xbc\xccn\xaa\xf2n\xf0\x1cB\bW\x15N\x9fA&o˸{K\xcaҹb\xa2\xc29O\xad\x8b\xc1\x83\xe5\xc3\xe8tx\xf4\x9a\x15\x91\xe3'\x145\xe9\xc4:'F?\xb5kV\x18\x95\xf4\xb4\xa8u\xeb\xa6q$V\x91Y\xc4\x1aǮtauzM؆\xb2\xe9\xe1\xedʫnj\x0e,\at\x1f\xa6k\xe6\xee)\xb4X몭\x9e(\xaa\xcf\xc6gWWd$\x93\xf5hE\xed\xcc\xe2\x04\xe9\xb5Rm\xe6\xe4n\xccbk\U000b3534\x8aWr\x13i\xac\xd44\xd8\x00\xf6\x8bſ\xff\xe5G\x1eJ\x12zi\x8dZ\xd7\xfc@\x8aO1o\xfc2Dz\xf1\xf3\xbc}\xb6c\x1e\xe3y\xbfc\x96\xa4QsYѮc\x82\xa2\x91\x93L\xa5\xf5\xfa\xe9\x9ed:1\xb2ѳ\x0f\xe7s\x12\xefY\xb5\x83\xe7\xb7l!\x9b>H\u008f[\xf0\xe6\x8f֦ޓ-\xaf9K\xac\xf8\x81X\xc1\xcds\xa2#\xa6\xa9\x978e\xfe\x94S\x9afK\xc9\x11.7<\x91379\a7\xa0\xf7\x9993\xa6\\Z\x01\xd3\x0eh]\x9547\x97\xae\xec\xf4\x95g%e\x95S\xfd\x9f\xcfMN+\xdco\xa3\x85t\xef\x86\x14\xe5\xad\t\xf7\x18;\x94\xe0\t\x1d\x9e\xe46L\x8e\"\xfd\xc1\xbe\xe9Q\x91qD\xb6\xbd\x1b&\x87E\xdd[49\x14\xf7\xa9\xcdwGNZR4\x81\xcbԉE\x1d\xe9\xd1\xe1ӏQI7DžG\xccX\xc6q\x99l@qܚ\xe8Љq\xe2\xf9\xa6\xcc\xc8\xf0\xb8Z\xf6\x1ao\xbbၙ\x80\x86\xf1t\x0e*u{B\xad\xab\xb7z\xa0\xa8>\xdbӛ\x92S\xf3\xe9\xe5:\x8ao\xb3(\x8a.ȑ\v\x03p\xa7ۚ1\xf7U\xc4\xd6\xe4\x17\x9b\xd2\x12\x1f:G%-5\r6@\xf1\xc5\xf6lKN\xcc9G\x93\x1a\xb5\x8e4?\x90\xf2Sl\xbe-\xfc\xb6\xcd\x1e[Y\x9c\x13\xe648\xcd\xfd\xefJ\xd3$\xed\x1f\x96\x84\x96\x18\x85\x98\xcb\xf3\xa1\xe9\xddF1\x83\xa6S\x98\xfa\xfa\x9dAԺ\xb0<68\xba<\xc7g\x06\fc\xad\x97M\xe1\xe0\x9f+\x87\x95\r\xd1^\x96\xdḑc\xe2:\xa3\x90\xeb\xc0,I\x0f\xa2\xd6\xfd*\xe9\xe1\xadug\xc3@?\xfc\xd0\x12\xec\x92\x1e\u0558&\xe9\x81\xe3WI\a7 \xe9\xe0\xa5y\x1f\xb7\xc4\xf4\xf5W\x9f\xb8H\x17;\x8d\xa2t8_\xc7?\xfd\xd6`w\x0eB@\xd2\xc1K\x1c\xc7q\x13\x9a\x8d\xa2F\x02t\xb1\xf3\x13\xa3(\x1dr\xc8\xce獢F\x0f i\x00\b*@\xd2\x00\x10T\x80\xa4\x01 \xa8\x00I\x03@P\x01\x92\x06\x80\xa0\x02$\r\x00A\x05H\x1a\x00\x82\n\x904\x00\x04\x15 i\xb38\x92\xfd\xe5\xf0Z\xb9\x00\xa3\x13\xf3$\xed6\xd0q\x15\xd1\xdb\x14\x15i\xddK(\x88\xd9˗\x92\x8b\x18\x87\xcf\xca\x05\x18\xa5\x98%i\xd9@\xe7\xb2\xfdMr\xab\"s\xff{\xc5\x1f0\xfe-\xe4\xfec\u007f\x12\x12\xc3f\xe5\x02\x8cR̒\xb4l\xa0s\xd9n\xaeџ\xdf`\xfd[\xce\vw\xc4$\f\x97\x95\v0J1IҌ\x81Ψ\x914{\x83\xcaM)]\xee\xe4pY\xb9\x00\xa3\x14\x93$\xcd\x18\xe8\x98(i\r\xa7\x16\xd6\x14GөŇX-7\x1e\xa5\u007fK\xcf=R'\xadm\xe5\x02\x00\x83\xc5$I3\x06:\x97\xed\x958YcB\xb3\xd6rja\\]\xb4\x9dZ\x8cc5\xddx\x94\xfe-\xef\b7\xf8\x16аr\x01\x80Ac\x92\xa4\x19\x03\x9d+4Y\xf2\xbc\xdf5\xad\xe7\xbb#\xb9\xba\xe88\xb5\x18\xc5\xea\xba\xf1\xc8\x03\xef:\xd6\xe0\xd2\xd3\xca\x05\x00\x06\x8fI\x92\x96\rt\x10:M\xc4\xec*\xf2{W\xa5\xe7\xbb#\xb9\xba\xe88\xb5\x18\xc4\xea\xbb\xf1Ȓ>\xc23\xff\xef\xefi\xe5\x02\x00\x83\xc7$I\xcb\x06:nj\xfc\xdeU\xe9\xf9\xeeH\xae.:N-\x06\xb1\xfan<\xb2\xa4\xcf\xf0g\xe4<<\xad\\\x00`\xf0\x98$i\xc6@\xa7\x92\x9a\x17\xa0*\x87\xd7\x1d\x86\x01=\xdf\x1dIz:N-\x06\xb1\xde\xddx\x04\xff\x96.\xf6\xeey\x9eV.\x000xL\x924c\xa0\xe3\xa0\xddsG\x91\x96\xb9䰢\xed\xd4\xc2\xc8Tǩ\xc5(Vύ\x87\xf5oY\x9b!\xdd\xffN\xc3\xca\x05\x00\x06\x8fI\x92f\ft\xda\xed\xfb\x9a?<V\xe0\xf7NZ۩E\xe1\xea\xa2\xed\xd4b\x14\xab\xe9ƃ\x94\xfe-\x1f\xf1\u007fp\x97B\xcb\xca\x05\x00\x06\x8dY\x92f\ft\x9c\x95\xc5E\x8e\xd3F\xf1Á\x86S\x8b\xd2\x14Gө\xc5(VӍ\a)\xfc[\x10z.Q\x9cMk[\xb9\x00\xc0`1Mҁ\xc8\x10\xde\x03\xbeo\x9b\x8dv\xdd\xc3h\xe5\x02\x8cN@\xd2\x03`\b%\x8d\xfa\xcaS\xbf\x18n+\x17`4\x02\x92\x1e\x00C)i\x00\x18\x1e@Ҿ\x03N-@\x00\x00\x92\xf6\x1dpj\x01\x02\x00\x904\x00\x04\x15 i\x00\b*@\xd2\x00\x10T\x80\xa4\x01 \xa8\x00I\x03@P\x01\x92\x06\x80\xa0\x02$\r\x04)\xbdF\x01A\nH\x1a\bF\x9c\xe9\x13\xb9YFA\xc1\tHz\xd4A\x9d{\xae\x9f\x91\xed\xfd3e\x8a\xbdҴ;Ϛ\x8by\x92v\x1b\xe8(\x93\xfe\xa52J\xfa7\xed\x8ę\xf0\x19\xa6\x8c\xd5>\xb1\xf1\x8b\x8cb\x10\xb9\xaf\x12\xe6Ό\n\x9f\xafH\xd5\xc9Wt\xee\xe9\x98\x1e\xf9\x98ƻ\x03`\x88\xbd\u007f\x1c\x91\xbe\xff˼\xfb{K\xe78.\xbcY#\xa0\x81ۧ\xb1ut`\x96\xa4e\x03\x1d6\xe9o\x1c\xe1\xd2\x1dϦO|*=\xfc\xb2\xb7\xe0\xe1\xa2\xef\xccF\x9bQ\f櫽\xfc\xfeƺ<\xfe9\xa3@7\xda\xf9\xba\x9d{\x96Lzl\xfcu\x9a\x16\r\xad\xf7\xcf2n\x99Q\x88\x84\xfb{k\xaf\xa9٬y\xcb\xe4Z\xaeFc\xeb\xe8\xc0,I\xcb\x06:l\xd2<:8\xdc<;\x8d\xa2\x86\x89R_$\x8dN\xf0\xadX\xa7[\xd8\xfb\x05\x1b\xa0\x91\xaf\xe4\xdcs\xfb:\x14~\xbd\xcd~H\xbd\u007fVp+\x8cB\xb4\xa8Ց\xb4\xdfo8;b0IҌ\x81\x0e\x934\x91f\xce\xf7aߐ3\x00I\xa3\x9e\xe4-F\x81\x12\x1a\xf9J\xce=\xb7\x15\xb5s\xd7;0\x1aR\xef\x9f5\xdc\x1a\xa3\x10-@\xd2jL\x924c\xa0\xc3$\xfd\xcb\xe5p\x8e\x1b_LR\xae(\x8e\xe2qˠ\xe2iᓗྻa\x02ǭh\x9e7)|F7\x93T\x05\x8b\xb7/j\x8f\x102\xe3\"T]\x98\x86]\x0fB\x17\xf3R\x93\xd7\n\x03dƂG3V\x904\xda2W7\xb6\xaf\";)K\x98l\xeb\xe4+;\xf7\xccX1\xeb6\xfcY&4i\x1f\xcd7#!\xd9\xfbG\xfc\xf0\n\xa4ݘ\xcc\x14\xf9*x\x8c\xa3s{\xed\xea\xcb\xe4B\xedK&\x87\xcf \xdb\xe4\uf360-\xde*\x90\xf4`0\xca\xda\x1b\x8c\x81\x0e\x93\xf43\xc7jj\u0084\x9e\xe1͚\xe7\xb9555\xea\xb9e\xfa\xf8L\xc7樘^\xe4*)\x8e\x9e\x1c\x11\xbdd\x1e\xf7!\x93TE\x8b7\x19t\x15m\x16P9fk\xd9\xf5\xa0\xf3\xc9\x19\xfb\x8f\xac\xe2\xa9\xf4d\v\x1e\xedXQ\xd2\x15|\x97^l\xbemG\xdd\x0e[\xbe~\xbe\x8csϚ\x88\xb0c\xdd3\xe2\x0e\xeb\x1c\xcd7#!\xd9\xfbG\xfc\xf0\n\xa4ݘ\xcc\x14\xf9*\xd8\xccљ\xb9v\xf55\x15O\xe0\xa2\xd6l\x88\xa0\xe7\xa5\xe4\xef\riJ\xba\xdbYu{\xa4Y\x93(\xf31IҌ\x81\x0e\x93\xf4?\xe1\ue9a15\xf0vpE\x88\xb4\x19j\x86\x11\xc3M\xbf\"N\x0f\x98$\x8b\xfbV\xc0\xce\x16\x01\xe5\x0f\x84\xb6]ON\x06\xd6g_\x16\x91\x1ec\xb6\xa3\x1d+J\x9a\x98\xefh\xc7\xd6\xf1'hX\x9d^\xbe\xacs\xcf:Ύ\xae\x84\x93\x0f}\x1dFB\xb2\xf7\x8f|\x1fd\t\xa5{\x90;3E\x92\xc5\xce\t\xfd\xbcv\xf5\xa1\xb0H\xdcCϋ\x12_\x85{\x93\xf4,\xdcǛ8\x8d2\x1b\x93$\xcd\x18\xe8\xb0^:~ǫ\xa4\xef\x9d\xe4\xea\xc6D\xd3\tcL\x98\xd4+3I\rZ87\x8aF\xaei\xd7sM\xd0\xc6\x0e\"=\xc6lG\xdb\xdaG\x94\xf4~\xfe+\x9d\xd8M\xc29\xabE\x1b\xf5\xf2e\x9c{J\xb8\xc8%h\xc3D2y\xb8\x0e#!\xaf\xde?J\xf7 \x9b\xd4+3I\x96\"\xfa\x03\xaaW}(\x8c|\vk\xc2\xc4W^%\xfd\xe1>\xfb\x14\xe8\xa5\a\x83Q\xd6\xde`\ft<\xbdt\xfc\x88WILjm\x8b\x8e\xf6bn\x97\xb7\xcbI-j\x1c\x02\xca\xf5dM\xbb\x9es\xc28\x98.c1f;\xda\xd6>\xa2\xa4\v\x93\xf5b\x1f\x14n?\x9c\x9b\xad\x97\xaf\xec\xdc\xe3\f_R\xf5\x83\x96I\xf4\xd3_\x87\x91\x90W\xef\x1f\xa5{\x90;3E\x92\xe5P\xa4\xa0M\xed\xeaCt\xa8훤15\x9c)=Ĉ\xc0$I3\x06:L\xd2\xffx\x95\xf4\xbcI\xc7)\x1d\xe4E\xcc\x1ci;\x93\xf4\x1dM\xbb\x9eo\x04m\xe4\v\xbd\xa9d\xb6\xa3m\xed#\xaex\xa7\xacՋ\xdd$XZ\xa7\xe5\xeb\xe5+;\xf7\x94\xe1>p֤\x88\xcbB\xbe\x836\x12\xf2\xea\xfd\xe3\xe9\x1e$\xc0$\a\xc0\xc0$\r+ރ\xc2(ko0\x06:L\xd2\xffx\x95\xf4>\xae\x84<\xad\xa0\x17I\x19KZc:ɠmד\x9d\x86g\xb0\x1f%\x12\xe91f;ڱ\x82\xa4\v\x89\x00\xb5c\xeb\xe8\xd6j2\x97\xd6\xce\x17I\xce=\xbb\xb8f\xf4&w/\xea\x8dn\xb9\x0e#!\xc6\xfb\xa7e\x8d\xc7\x191ŁA\xd2~\xc3$I3\x06:lү\xb8\x0e\xd7Ԅ\xa5\xd7\xd4\\q\xafx{\xb4\x82eܽ%e\xe9\\1\xea>\\39\xae\xa6\x864v&\xa9BkїAˮ\a\xb5&\xa5\x96\xeeH\xe6m\xfb[\x15f;Z\xb1\xc2\xd5c\xf9<\xed'\xb5c\xf3\xf8\xc2W\v\xf9<\xfd|%\xe7\x1eg\xf8\x9c]ѓC3ׅ:\xaf\xc3H\x88\xf1\xfe\x99\xc5\xc5!5\xd2nLf\x8a|\x158\"\xbc\x8cӜ5\xa1\xe9\x87\xd1\xf1\xf4\xd0\x1a'\xfb\xbdѫ\xc76\xd7\xd4x\xacm\x1c\x1b\xc5n\xa0fI\x9a1\xd0a\x93\xfe\xa4v\xbc0U\xb6#W$ML\xf0\xb8\x80m\xdf\xf4\xa8ȸ}\b5\b\xa1\xa4\xb13I\x15Z\xa7fY4\xecz\x10:\x9f\x9b\x9cV\xb8\xdfƓ\xebG\x18\xb3\x1d\x8dXz\x8d7\x9f&\x0ey5c\xfbʳ\x92\xb2\xca\xfb\xbc\xe4+9\xf7TN\x8e\xca쬜\x1c\xf9\x94\xce\xd1|1\x12b\xbd\u007f6\x87E!\x0fܻ1\x99)\xf3e\xd9\x17\xe5\xe5\xb2\xecL\\塧\xc3\xf1c&\xf3\xbd\xd1k\xbc\t\x1e\xc3&\xe7\x849\rNS\xae\xd87\x1f\xd3$\r\x98\x83۹\xe7z\x10\x96ǔ\xde?\xb3\xa6\xebE\x9bB\xd9\x14\x0e\xfe\xb9r\xc0\x18e\r\x8cH\x04\xe7\x9e\xeb\x82JZ\xe9\xfd\xb3nĝ\tv6\xa8\xaf\x1c\x1a%\x80\xa4\x81\x01\xe3i$\xd4\x1e\xb5Y3\x12\xf0? i`\xa0\x80\x91Ј\x06$\r\f\x140\x12\x1aр\xa4\x01 \xa8\x00I\x03@P\x01\x92\x06\x80\xa0\x02$\r\x00A\x05H\x1a\x00\x82\n\x904\x00\x04\x15 i\x00\b*@\xd2\x00\x10T\x80\xa4\x01 \xa80OҢkNw\xb1]\xa0\x18\x01\x00pݘ%i\xc95\xc7e?\xee\xc4\x1c\xb37\x18\xed\x12\xe8T\x1dG\x000\xec\x98%i\xd95\xe74\xb9ۯ\xab8\xf8\xefBq\xfb`nY\x06\x00\x03\xc4$I\xab]s\x1c\xfe\xbfO\x91\xdf\x19\xd4]\b\x01`\x80\x98$i\x95kN\x93=x\xfe]]\xe9\xb0\xe3\xb6\xe0q\x88\xb7ԉ!7\xdd\x19_\x8cZB\xb9)\x8aX\xd6\"\x86e`.4\x00`\x92\xa4U\xae9%\x95^\xa3\x03\n\x85Îd\xc1\xd3y\x88ޅ\xb0\xa6\x89\xde\x1ao\r\xfeQK\x0fS\xc4*,b\x18\x06\xe6B\x03\x00&IZ\xe9\x9a\xd3b\x1fBS\xd3\x11\x80䰣\xb4\xe0\x91\x06\xde\xec\rle7\x1e\xa5E\x8c\xc8\x00]h\x00\xc0$I+]s*K\xbcG\a\x1a\x92Î҂G[Ғ\x1b\x8f\xd2\"Fd\x80.4\x00`\x92\xa4\x95\xae9E\xa6ܖ\u007f\xf8\x90\x1cvb\xc4\x19\xb4`\xc1\xa3-iɍGy\xf3y\x91\x01\xba\xd0\x00\x80I\x92V\xb8\xe6tؽ\xd9T\x04 \x92x=-x\nH\x9fLŻ\"L\x19\xab-\xe9\xa1u\xa1\x01F\x01&IZ\xe1\x9a\xd3b\xbfl\x10\x1e`H2UX\xf0\xc4\xc5!\xe4\xa4\x1b\u0097!\xd4{\xbbO\x92\x1eZ\x17\x1a`\x14`\x92\xa4\x15\xae9Mv\xf7\xcaw0\xa0pؑ,x\x10Q놲\xe9\xe1d!pZԺuӸ\tEML,k\x11\xc320\x17\x1a\x000KҬkN\x8b\xdbw<(P:\xec\xb8-x0\xae\xcc\xc8\xf08\xba\x1e\xd8\x1c\x17\x1e1c\x19\xc7e2\xb1\xacE\x8c\x82\x01\xb9\xd0\x00\x80i\x92\x06\x00`8\x00I\x03@P\x01\x92\x06\x80\xa0\x02$\r\x00A\x05H\x1a\x00\x82\n\x904\x00\x04\x15 i\x00\b*@\xd2\x00\x10T\x80\xa4\x01 \xa8\x00I\x03@P\x01\x92\x06\x80\xa0\x02$\r\x00A\xc5(\x96\xf4\x1c.j^\x93Q\x10\x00\x04\x18\xa3X\xd2Ϊ\xa2)Q\x9dFQ\x00\x10X\x98'i\xd1@\a\xa1\xceC\xbb\nv\x1d2E[U\\\xd0{|\x00\xa3\r\xb3$-\x19\xe8\xa0\xcbŻ\x9aڛv\x15\x9bqg\x93Z\xee\xb0Q\b\x00\x04\x16fIZ6Щ)!7B\xe8.\xa91\xdae\x18\x00I\x03A\x87I\x92f\ft*\x85\xbb\x84\x96\x99qw~\x904\x10t\x98$i\xc6@\xa7\xa3\xb8\xaa\xc3\xd5QS\xdc\xe1-~\x98hઌB\x00 \xb00IҬ\x81\x0e\x9eV\xdb\xed\xfbL\xb9\xa3\xa0+jڡ\xf6^\xa3(\x00\b L\x924c\xa0\xe3\xaa,ir6\x95T\x9ab]\xb9\x8f㸻\x8d\x82\x00 \x800IҌ\x81N\r5\xc6r\x95\x98a0\xdd\x195isU\x90\xf9\x02\x00\xa3\x1c\x93$\xcd\x18\xe8\x14Ѕ2\xf4f\x81\xb7\xf8a\xa2\x963cQ\x0e\x00\x86\x11\x93$\xcd\x18舒>n\x8e\xa4a\xc5\x1b\b2L\x924c\xa0S%\x0e\xbc\xcdX{\x06I\x03A\x87I\x92f\ft\\ϗ\x9cn?]\xf2\xbc\x19KއA\xd2@\xb0a\x96\xa4\x19\x03\x1dW\xed\xae\xa2]\xb5\xfeW\xb4\xcby|N\x98Ҁ\n\x00\x02\x1e\xd3$m>\xb38.\xba\xcc(\b\x00\x02\x8cQ,i\xe7\xf1v\xa3\x10\x00\b8F\xb1\xa4\x01 \x18\x01I\x03@P\x01\x92\x06\x80\xa0\x02$\r\x00A\x05H\x1a\x00\x82\n\x904\x00\x04\x15 i\x00\b*@\xd2\x00\x10T\x80\xa4\x01 \xa8\x00I\x03@P\x01\x92\x06\x80\xa0\x02$\r\x00A\x85y\x92\x96\ftz\x1b\xca\nv\x8d\x1c\xbf\xb9\xd6\xdc\xe4䜓Yg\x8c\xe2\x04N\xa4\x1c\xd1\u007f\xb3\x94\xb7\x91w\xeb\x92\xf8R\xed\x80-<_\xad\xfd\x0e\xfa\xc4\xc6/\xd2ykh\t\x88B\x02\xbec\x96\xa4e\x03\x1d\xe4(:\xder\xac\xe0\x98\xd1\x1e~\xe2][\xee+չ\xfa\xadXūI\xaf\xe8\xbf\xf9E^\xd2C\xf8\xe9\xa1ļ/\x94o\x9c|Wx\xbe\xd8h\xd3\xd1\x11\xea;\xb3Ѧ\xf3\xd6\xd0\x12\x10\x85\x04|\xc7,I\xcb\x06:o\x16\x90\x9b\xf27\x17\x98\xe2s\xe7ɪ\x9c>\xdcT7\xfa*i\xd4\xe7\xed\xcd\xc2ܤk\xe8\xab\xc4\xdcB\xd5\xf6\xec\xb5\ue52eZp\xf7\xe9'\xb5\x04D!\x01\x9f1IҌ\x81\x8ec\x1f\xddR<B\xba\xe94ڲ[y/\xe3i\xdf)\xcc{\xa8\x1a\xfdiU\x9eZ-Y#I-\x01QH\xc0gL\x924c\xa0\xb3K\xf0\xb7+s\xe8\x06\x0f\x0f\xef\xdbx~\xc7\xf9\xfc\xb4\xc4U߲\x9b\xf3RZ\xf1c_]\x17y\xfcSvR\xc6\xd3]\x8a\xd8j\x9eǓ\xceR\x9e\fͯ%\xf1\xf2\b\xfd\xfcڹ\xb6\x94܋\xecnX-\x15\xb9(\xb7\x82\xaaE\xdaz\x84\x17\xc8&{\xd9\n\x9f\xceHZE\xf6B}\x15\xd9IY\x15\xb4\u05ff\x98\x97\x9a\xbcV5\xa6m\x8f\xe0\x04\"Twn\x90\x0f,\xa1\xf8lrqPWᢤ\x9c3\xa9u\x8a\xfd\x87\xb2\x90\x80\xf9\x98$i\xc6@\xe7P1\xbdCh\xd1.\xa3}\x86\x98\x9e\xea괌{R\x9fλ\xf3Sv\xf3\xa7i\xfc\xaaҷzhz\x13\xbf\xad\xae<%\xab\x8f\x8d\xedjL~\xeeK\xf4\xe5sɍ\xb8\xe1\x9fklL\x14{\xb0\x93I\xd9{O\x94\xf2\xe5\xecnX-\x17\x93\xbeI\xfc\x8c\xaaE\xda\xdau\xa61#\xa7\xb1\xb1\xf1#\xb2\x9b\x8dϨ>27\x97$\xf3m;\xeav\xd8\xf2q\xea|r\xc6\xfe#\xabx\xa5Z\\E\x9b\x05\x8a\x94\xb7ic\x0e,\xa1\xf8lrq\xae\xa5%\x97\xd7m\xe1\xf9\nE\x06CYH\xc0|L\x924c\xa0\xd3Y\xe4p\xba\x9ce\xf6\x12\xa3}\x86\x9e,\xfe\xa1k\xa8\xef\x9ar\xe3W\xa5\xbf\xb2\xf1ɤ\xef}\x95ߏ\x1f\xcf\t\xfd\xb0\x1c\xbb)\x0f?\xe4m\x12\xc3EI\xf7\xa4\xad\xea!R\xfaJ\xb1[a\x1e\xcaژ\x8d\x88Z\x94\x99\xc9cڔop\x8e)8Uǟ\xc0\x8f'x܅\xe6d\xe0\x9f\x8b\xbe,\x95Z\x9c-\x02\xca; 2\aV \x95\x979p~2\xe9i\xb7yHz\b\v\t\x98\x8eI\x92f\ftP\x87\xc3n\xb7\x1fv\x98pg\xbf,\x9b\xa2\x83\x96\xe89\xb1\x8a4ڼ\xb4\x9eo1\xa9\x9b\x94\xb1'\x13\xbbPW\xd2I\xf1\x95(\xe9:\xfe\x03\xf7\xde\xccnX-{\xf9\xbdT-\xca\xccd\xb5\x90\xd7tB\xbaI8\x1d\xb4h#\xba&hn\x87R--\x9c\x1b\x85\xe3\x0fs`\x05Ry\xe5\x03\xf7%Ѳ\xb6zJz\xc8\n\t\x98\x8fI\x92f\ft0\xae\x8e^Tl\x82'VV\xb6\xe7\xb6s\u0094\xf1\xc1\\\xd2\xd1\t\xe4*c\xbfM>\x82\x8e\xccu\xaft\x8b\x92.\xe7{\xdc\xef3\xbba\xb5|Q\xf8%U\x8b23\xe5\xca\x13U˃\xf4\x1d\x94\x9b\x8d{\xc9F\x84<W\x9ej\x1c\x025\x8a\xad́\x15H\xe5\x95\x0f|QX\xf3\xeb\xf2\x94\xf4\xd0\x15\x120\x1d\x93$\xcd\x18\xe8 \xbaP\xd6l7\xe1\x8e\xdar\xa3\x95I\xd9F\x9f\n3H\x9f\xf5.\xe5\vU\xec\xb6\\\x94\xbb\xcd\xfdB\x94\xf4\t\xfe}\xf7\x16f\xb7\xc2<aK\xa1Vf\xfbI7*\xabeS\x1a\xf9\x95\xe8K\xcbG\xdf\xf0\xe5\xbd\x1dW\\\xf9>\xa9\x859\xb0\x02\xa9\xbc\xf2\x81\xc5^\xfa\x03OIӸ\x81\x16\x92\xe6\xe2[!\x01?b\x92\xa4\x19\x03\x9d&\"\xe6+\xc5f\xf8簒nY'\x8cg禒Yi\x1fy\xeb\x840\xa7,ܫ\x8a}+\xf1\xb3ķ\xdc/DIw\xa5\xe4\x90\xder\xdb6\xc5n\x8cZ\x14\x99\xe5\xe4 \xf4%\xdd \xab\xa5\x8e\xbe\xae&#\xfe\xec\xff\xfaј1?\xfa\xb9Oja\x0e\x8c\xe4O\xc1\x94\x979\xf0ڹX\xab}\xf9\xa2\xa4ݱ\x83-d\x1a\xae\xa8\x8f\x12}*$\xe0GL\x924c\xa0\xd3l\xafm\u007f\xb3\xd8\xe1w\xb7\x8doߢk\xba\x9f\x88/gq3\xe8\xf3\\>\xa5\xb4\xee\xc8CId\xa9\xb7\xf0μW\x8el\u00adX\x19ۗ\xba*\x95\x8e\xbb{\xce46&nll$\x8bf'\x13\x17U\xd4\t+O\xd2n\xdf\xe4\xe5|\x86_\u007f\x96\x93\xf7\r\xb3\x15\x11y\x94\xe3C|\x8a>k\xb4m<\xd3\xf7\xceF[#\x8e\xcb\xe3\v_-䉾\xde\xff?\xdf).\x18\xf3\u007f\xff\xb3\xa2\x15\x19\xc3\x1cX\xfa\x14\x8a\xf2\xca\a\xfe,%\xad\xe2\x95\xdcDe\xec`\vٚ\x94Z\xba#\x99\xb7\xed\xf7\xa5\x90\x80\xff0KҌ\x81\xce\xf1\x92\"\xc7q\xa3\xf0\xa1\xe7}fڈ)\x8a\xb2\xd3\xe7_U\x14.JJɥ'oЉ\x9c\xb9\xc99u\x1e\xb1\xe56\xe1\x94\xd1;\xe2ԓJ䣵\xa9\xf7d\x1fQ\xecV\xca\xf3dai#O/\x9fvo\xc5\xf4lKN\xcc9G/\x9f\xe6m\x1f\x90\xb3\xdb[\xf0/EyVRV9\xf9\xadp\xfdpV\u007f\u007f\xe4\x8f~N\xb6\x1a\xc3\x1c\xd8\xfd)\x94\xe5\x95\x0f\xfcŦ\xb4ćΉ\x92\x16c\a[Ht>79\xadp\xbfͷB\x02~\xc34I\x03\xfatF\xce\xc1\x92\xbe\xadyxF.\xea\xe51 \xb8\x00I\x8f@\xa8\xa4#nk\x02I\x03\x03\a$\xad\x84\x1f\t\xfc\xe7\xffƒ\xfe\xe1\xff\xfa\xb7\u007f\xfb\xf9p\x88\x1a$\x1d܀\xa4\x95\x18\xa9\xcd/PIG|\xe7\x87\xdf\xfdN\xc3.\xc7\xe5n4\xa4\x9c\xaf\xe3\x9f~\xcb\xeb\xff\x8f\x01\x01\rHz\x04B\a\xde\x13;\xfa\xbbC0\xa1\x87\xdb;\x87R\xd59\xf87\xc3v\xde(\n\bX@\xd2#\x8f\xde+D\xd2w\xe3*\xfe\xde,W\xf3ؐ\x90\xef\xd9;{\x8dv\x02\x00\x01\x90\xf4\x88\xa3%.f,\x96\xf4f\\\xc5ӛ\xfa\xfbӗ\x1c\x8a\v\x99\xde\x01\x9a\x06|\x03$=\xd2pE|\xef\xf6\x1b\xb0\xa4kq\x15/\xfb\a\x96\xb6\xb3\xbf\u007fF\xf80\x9d\xd0\x02\x82\x0f\x90\xf4H\xa3!\xe4p\u007f8\x964\xc2U|\f\xff\x1d\xc6\u007fs\xc2\x1aF\xc8}\x9c\x80\x11\x0fHz\x84ѻ!\xe4\x1f\xfdd.M\xf8\xa7\xf8\a\x92\x06|\x06$=\xc2\xe8\xce\xfc^\u007f\xff\xc49\xfd\xbd\xae\u007f\xf6w\xe3?\x17\xfe\x03I\x03\xbe\x03\x92\x1ea\xb8\xe6\x85\xf5\xf7\xc7d\xfe\xf3\x1f\xfd\xc7\xff\xf1\xcf\xfe\x86\xde\xfe\xfe&\x9040\x00@\xd2#\f\u05ecHZ\xbb\x9b\x1fs\xf6oXw\xa5\u007f\xdd:\x04\x92\x06\x06\x00Hz\x84\xe1\x9a\x1e\xfdO\x0f@ҀϘ#\xe9\xeeb\xbb@1y\xe5,+\xdag\xc2=MF&\xaei\x93\xff\xe1\xc1,\x904\xe0+\xe6H\x94>:\xac\x00\x00\f\bIDAT\xdae?\xee\xc4\x1c\xb37\xe0\x17\xed\x055\xcd5\x05\xaa\x9bS\x8fZ\\\xd3&zn\x8c\x8e\x02I\x03>b\x8e\xa4\xd1iz\xefnz\v\xc1^\xfax\xa8\x18.\x8f\xa2\xb8\x96\x8d\xa9\xb9\xa2bWȽ\xa7AҀo\x98$i\x8a\x83ܧ\b5\x15Py\x17\x8c\x1c\xefJS\xe9m\n\r\xb9Ổ\xb1\x84\x1b0!?(iq\xa1\x90\x00\xc5\xe8\x13\x03C\x8b\x89\x92n\x12n\nZ)xb9̸\x9f\xe0H\xc4uzŬ\xe9230\x99\x8e\x86˽(\xe4j@\x02\x92\xf63&J\xba\xa4\x92>\xed\x12n\xe0}Ȅ[\xf3\x8fL\\Ζ&\x05\xcd-N\xf2\x9fX i\xc0\x17̓t\x8b]X\x11+\xae\xa5O\xb5\xc5ނG\x17\xdd.%\xddt\x9d\x01$\r\xf8\x82y\x92\xae\x14M\xb0D\xe7\xca*\u007f\xdb\xdc\x05\x1c i\xc0\x17̓t\x91h(M\x1d7\x10*\x83\xb9\xb4\x01D\xd2O\x8eŏ\xac\xb6C<\x12\xde\xf0)HB/Z7\x17\xcd7@\xd2~\xc64Iw\xd8E_\x88&;q\xbc\xbbb\x87\x15o\x03\x88`\xc6\xfd\xf9\xaawI\u007f~\xdfMcn\xf8\xe9\xee\xab\xdahi.\xe4\x16\xe1\xf9\x16\x8fl}\x94t\x88F\x8a}\xdb\xe8s\x01C\x8bi\x92n\xb1_\x16\x12\xbd\xd4;\xa7\n\xceK\x1b\x11\xa2%\x1a\xb5\xa4\u007f\xf1\xb3\xd7?\u007f\xfb\xc9[\xd5a^\b\xb9\x89\xfe\x00\xec\xbe\xe9\xfa%\xad\tH\xdaϘ&\xe9&\xbb\xfb>\x1d\xed\x05U-Up\xf5\x98!d\xc8-\x80\x85\xf2\xcc\u007f\x8c\x19w\x9f\xa8\xa7G\xc7\xfd\xeb\xb8߈\xc2\x1a\xf37\xb7\x94\xa4\x88\an\f\x19{\x01'.\x8c}\x9b\xeey\xf3\x98\x1b\x1fe\xdf\u007f\xfc\xc7$\xfcǏ3\xd9\nG\ty\xfc\xe61c\u007fA2\xfc\r9\xc2Uա^\xff\xe9\xd817?\xee\x8e\xc5G!\x85a\xf6\xb9Q\b\x05I\xfb\x19\xd3$\xdd\"/\x879\xf7\x15\x94\xc15ކH\xbd4~x\xf1\xdf_\xbc\xf0\xfa\x8f\xef\xa3\xe9\xdf߸\xfb\xc2\xee\x1bE\x9d\x8d{QT\xb4\x1cq\xeb\xdbW\u007f\xf28\xde\xf2\xf8Oh\xf4w\x9f\xb9\xf0\xfa/\x149܄G\xf3\u007f\xfe\xbe:[\xda\u007f_x\xfbg?\xc3B\xbfq\xf7\xe7\xbbo|Fu\xa8\x9b\x1f\xf8\xdb\xe7/\xfe\xc4\x1d\x8b\x8fB%\xcd\xec#\x84\x82\xa4\xfd\x8ci\x92\x06\x06\n+\xe9[ɜ\xfa\xedqB\x1ak\xed\xea3\xa2Ξ\x19\xfb\xd3\a\xa8\xaa\xe5\b\x9c\xa0#\xf1[\x9f$ѷ<)\x0429<\x8e\x15\xf8\xb3'\xd5\xd9\n{^\xfd\u007fc\xf1>\xf4\b\xb7\xa8\x0eu\xc3\xdb³\x1c\x1b\xc2\xec#\x85\x82\xa4\xfd\fH:``%=\xd6=\x02'i2\xcc\xfd\x9b\xa8\xb3\xab\u007f{\xf4\xae\x9bIW-G|~\xf5\xea\xe7c\u07fe\xfa\xf6\xd8\xcfI\xb4{d\xce\xe6\xf0\xfd\xd7_\xff\xbeG\xb6\xe2\x03y\xbc\x81\x1e\xe1\x06ա\xfe{\xec]\x8f\xbe-\x95\xe9sQ\xd2\xca}@\xd2\xfe\a$\x1d0\xb0\x92\x1e#\xf6\x90\n\xf1H<\xfe}e\xc4իw\xddw\xf5\xbe\xbb\xe4\x1f\x80\xab\xca\xf7\x9f\xbc\xeb\xae'=\xb2Ւ\xb4\xf2P\u007f~\xe0\xa77<\xc0Ƃ\xa4G\x02 送\x95\xf4-\xbf\x91\xb5\xa7\x18\rS\x88\xfa\xd8\b<I\xbe\xe9\xeaM/\n\xd1\xe2\xc0[\xf1\xfe\xcd7_\xf5Ȗ\x91\xa7\xf6\xc0\x9b\xf0\xfa\rz\x92\x86\x81\xb7Y\x80\xa4\x03\x06Vһ\xc7>\xfa\xb7\v\xbb\u007fLӊ5\xab[\x9f|\xfb\xf3\xd7\u007f\xf6\ve\x04\xe6\xa6\an\x12\xf7\xbc\xf1\xf7tyL\xf5\xbe*\xdbq\xbfw\x1f\x8c<\nK]\xea\xe5\xb1\x1f\xff\xfe\u0085\xdf\xdc\xccƲ\x92~f\x1c\x0e\x1d\a\x92\xf6? 送\x95\xf4\xd5ݷ\x8e\x19s\xebn!\xfd\xe8\x8d\xf2\x99\xa5\xdd?\xbda̸\xff\xbe\xa0\x8a\xb8z\xf5\xbe\u007fu\x9f\xf2z\xe6?\x84\x93X\xca\xf7U\xd9>3.$D\x96\xe7\xd5ߌ\v\x11Ob1\x87\xfa\xfd\xadc\xc6\xfe\xe4u6\x96\x954=\x89\xf5\xc0\x18\x90\xb4\xdf\x01I\a\f\x92\xf6\x02\a<\xde\aI\xfb\x1b\x90t\xc0\x10`\x92\xfeş/\xbc\xf8\xef\x0f\x80\xa4\xfd\x0eH:`\b0I?\xfa\xfd17aE\x83\xa4\xfd\rH:`\b0I\xbb\x01I\xfb\x19\x90t\xc0\x00\x92\x06|\x01$\x1d0\x84\x04(F\x9f\v\x18Z@\xd2\x00\x10T\x80\xa4W\xaf\xd6J\x02@\x80b\x8e\xa4\x95\x06:\bU\x99wK\x93\xbfZ\x9e\xd0H\xbayقI\xc0\x89\xf7~\x19\x1f\xbb\xf0\xe8\xfc7pr\xeb\xcc;\xa6\xde1s;B\xf5\x16\xcbB\x84\x0e\xe0\x88\xa3\xea\xfd\x86\x89\xa3\xf1\u007f\x91\xd2mS-\xb3\xbd\x84z\xe7a\x8b\xe5\x80Q̀\x18\xba\x8aZ\x8dìmFQ\x80.\xe6HZa\xa0\x83\x90\xd3^k\xb0\xc3\xf0\xb1\xd2zI#\xe9\xc6\xf5F}\xec\xf2\xf7\x10:;u遗\x96S\x1d\x1c\xb5\xfcr\xcf\xc1\x17\x96Z\xea\x91\xeb\xa8Ŋ\x1f\x0fX\x8e\xba\xd0\x10s\xf4\xac\xe6\xe6\x83VF\x88\xa7V[5\x83|\xe1R\xfd\xd4\xedF1\x03b\xe8*\xea\xe3\xfa\xfa\xff\xb1\xbca\x14\x05\xe8b\x8e\xa4Y\x03\x1d\xac\xe8\x12\xf3$\xddfY\xaf\x91d\x89']\xf7\xe2\xc5$\xb9\x9a\xb4\xd4\xf5\xb1\xb4\xec\xb18\xd8eY\xb9\x9a\xec\xe7CC\x1d \xf3\x97\x1bE`\xb6\x0f^\xd2\bY\x87V\xd2h(+\xea\x14H\xfa:0I\xd2\x14\xc1@\aU٫\nL\x93\xf4j\xb9g^\xed\xd9I\x13hKM\xd8J\x92\uf456\xbax\x01ݼ`1i\xa9Gq\xb3\xf5\xb9\xa5\x0e\x80\x80\x95\xf4\x90T\x14H\xfaz0QҢ\x81\x0er\xb9ܷ\xe7\xf7?mS\xd7k$\x15Ж\xba<\xfe=\x92>\x88\xdb\xe4BAm\xcb\x17\x92\x96\xda6\xff\x80\xba\xa5\x9e\x9dj\xb1lm[\x99`\xbd\x9f\xdc \xf1\xa5\x85֙\xeb\xe9\xfb\xae'f\xc7.|#\xe1 z\xc4byI\x9e\t\xcb\x01\xf5\x8b\x13\xa6\xc6\xff\x12\xcfG\xffb\x11\x98\x8f\x14|m\xb5\x90=)\x97V\xc6\xc7.\xf7\x1cx\xb7-\x8f\xc7Y\xe0_\xa6N\x9cHXJF\xef\x8fX\xa6\xeeY?Ӻ\xf8cU\xa8u\xfd\xea\xf8;\x96\xb6Ѵ\\\x06\x19\xcd\x1c\x0e\xe2\x12\xfc\x16m\xb7h\xce\xc4\aZQdn\xbd]\xccL>\x1aA\x94\xb4^E!\xf4B\xfc\x1e\x04\xe8`\xa2\xa4E\x03\x1d\x82i\x92^=\xf5c\x8d\xa4\x02\xdaR?N\xb0ܿ\xfd\x14\x1dT\xcc\xff5\xdd\xfc\xeb\xf9\xb4\xa5\xee\xfc\xa5\xba\xa5\xba\x0e\xbc\x94036a\xfdJ\xcb\xc7d\x04\xba\xfe\xe0\xce\xf8\xf9X\xdc_'\xc4\xef<\xf8\xb0ŲG\x9cNJ3a9\xe0\xace偣{\xe2-\xbdd^:sa}}}\x9b\xaa$g\xeb\xebž\xb5-v\xe6\v\u007fYlQK\xfa\xb5\xd8\xf9\xbf;\xbaݲ\x93ho\xf5k\a\x96ZN!\xf4ח\xa6Z\xe2\xb7\xef\x8cUw\xfbV\xcb\xfc\x97^\x9ao%\x02\x94\xcb\xc0\xa0\x99\x83덄\x87/\xa1K[c\xeb5\xfa\xdb\x01WT}\xecVwf\xf2\xd1\b\xa2\xa4u*\n\xb3\xdcr?\x02t0O\xd2n\x03\x1d\x82Y\x92\xfex\xea\xc3\x1aI%\xb4\xa5\xa2\xaf\x9f]0\xd5\x12K\xfa\xa6\xd9+\xe9敳iK\xbdd\xbd\xe49\x9e\x9coY܉\xfb9\xa2\x8b?\"\xd2Bqߺ2\x96\f\xeb\xd7[H\xf7B\x85I\x87\xcdL\xc0\x9ex\xd2\\\xff'V\xc8Ag\xe0-Jz\xe1L|\xc8\xde\xf9*I\xbb\x12\xeeǛ\xbb\x0f|M~WH\x99\x84\\\xac\xb1\xf8\xb7ee\xbc:\xa7\xd98\xc25s\x81\xa2\flf\xda9l'C\x87\x95\x9a'\xfb\x06^Q\xabI\xee\xbf&\x99\xb1Gc\x06ޚ\x15\x85i{\xb6\r\x01:\x98'i\xb7\x81\x0e\xc1,I?2\xb5M#\xa9$\xde}f\xcbu\xf4~\xcbA\xa9\xf3Y.t>\xe8\x97;5$m\x15;\xfc\xe5\tݽ\x98\x04\xdcj\xadt\x92\xf9W\x95\xa4\x99\x80\x8f\xe3\x13\x1e\xd9s\x16u\v9x\x95\xf4\xd74\x17\xb4U%\xe9\x83\x16y\x9d\xfc\xef{\xeeO\x88\x15\x86\xeeV\xa2\x19\x8fy\xb7\xf5\xb7\xe4q\x8f\xe5k\xb6\f,\xda9|ly\x0f\xb9b5\xcfE\r\xbc\xa2^\xb3\xba\x90\xcbZO\x92\xcc\xd14%\xadSH\xc0\x13\xf3$\xed6\xd0!\x98$\xe9K\xd6\xd5\x1aI\x15\xb4\xa5\x9e\x12V\xce\x16.\x15\xfe0K\x85)\":0_C\xd2\xeeY\xf0|qV\xbc\x1cK\x81\xce>]*I\xcb\x01X\xa8{\x96϶\xc4\xffN\xd8ѫ\xa4\xcfZ\xa8\f\xd42\xdd)\x17\xe4T|\xc2\x13\a\xea\x17ϗ\xf6\xf1\x944ͩ\x1e\xff\n\xb0e\x90\xd1\xcb\xe1\xfe'\xd0\xd1\xd8n\xa4\xc1\xc0+\xaa7\xfe\x00z\x99\x0eNأiJZ\xbb\x90\x80\x06\xa6IZ2\xd0!\x98$\xe9\xf5\xb8\xa5y&%z\xe9&\xdaR\xe3\x1f\xa1[\xb6\xceDHlw\xf3\x17\v-\xd5e=\xea)iw\xc3[\x99p\x96\xf2w\xd4+H\xe8=YҴ\x8f\x95\x03\xd0Yr\x9c\xaf_\xb2\xee\x91rx\xc1sr/\xe4\xf2w\xa1\x97V/\x8f\x1d\x95{\xe9\xd9\vH\x99\x96{\x934]\f|\xc1\xd2ɖ\x81A/\x87\xbf\xc4w{\\d7\xe8\x8aZ\xbf\x1c-\xa7\xe5`\x8f\xa6\x96\xb4\xba\xa2\x00\xef\x98&i\xc9@\x87`\x8e\xa4\x8d:\xe9=\xa43\xfc;YmB\xf1\t_\x93-Di\xe2\xe9V\xb2\x03i\xa9h\xf5\xaf\xf5%}T蛷>K\x96\x82Ik\\)H\x1a7\xfe\xde\x05Ve\xc0v\xe1Ҫ\x85tJ\xbf\x10wm\x974\x96\x95Ź\xf4\x02R\x9c6\xabJ\xa6\xae\xf8\x85\xa4\xfb\\\x8fE\x92@J\xd0;ߛ\xa4\x13ȼ{\xf6BE\x19\x18\xf4r\xe8\x8e\xff\xcb\x1d\xeaq\xf7\xa0+\xea\x94\xf5\x92\x95.\x89\xb1Gc%\xadUQ\x98\xb6\xedm\b\xd0\xc14I\xcb\x06:.\xa7\xb3\xa8\xcai\x82\xdd\xc6\x13r\xcf\xfc\x84F'M.\u007f:\xf0\xc7\x05\U00064bcc\xb7\xc4o=z`1\xb9P\xf1\xa8\xe5\xfe\x97\xeb_^ly\x99\\\x14u\xc0\x85\xea\xadʖ\xda{\x8a\xaeW\v\xf9=a\xf9\xf5\x81\x97W\x93E\x9dK\xf1\t{\x0e,\xb7RI/\x8c\xffݳ\v,S\xff\xf8\x1e\x1b\xb0\xdd\x12\xbb\xf5\xe0\x81Ֆ\xd7\xc8~ۭ;_^lU\xf6\xd2\xddo\xd4\xd7[W\xd7\xd7w\xe2\xceޚ\xb0}\xeb\x1dB\x0e\fG\xad\xb3\xf7\x1c\\oy\x81d\xb6|ϳ\xf3\xf10\xfeԥ\xfa\xa9\xabO\xa1\xb3\xab\xa7\xd6+Ϻ[-\xf7\x9f:\xba0\xb6\r\xb1e`\xd0\xcdቄX\xb5}\xd9\xe0*\x8a\x10\xbfXX\xb6\x93\x8f&\\=\xb6\xb3\xbe\x9e\xe4\xa6YQ\x98\xa5\xe4\x02S@\x1b\xd3$-\x1b\xe8\x1c\x13.\xf7\xbe\xe2-z8\xb8d]\xa9\x91d90\xdf\x1a\xbb\x94\xaaf\xc1\v[g[\xe3\x85Ӹ[g\xc6Zbɥ˯\xd1S\xaa\xbd\v\xe2\x15M\xfc\xac0\xe9\x13&\x92\xe8\xe8\xe2\xf8\u0605\aI\xea\xef\xab\x13\xac\x8b\xcfRI\xb7-\xb4\xc6.\xfe\xad\xc5\xf20\x1b\xf0\xd2\xc2\xed\tS\xe3\x17\xbeFws\xad\xbfú\xf0\x14R f,\xe4\xb0\xf4\x8e\x84'\xfe8բZ\xa5o[\x9e\x10\xbb\x80tg\xbd;gZ㗿0s\xea\u0087\xf1\x1eS\xdf#\xa7\xb4\x95\xb1\xb3\xb7/\x8f\x8d_)\xc8\\.\xa4\x8cn\x0em\x16\xcf\x01͠*\x8a\xb0Ӻ\x93>\xcbG\xa3\xd7x\xbbg͚\x15EwS/\xe0\x03\x12\xa6I\xda|~k\xf9\xabFrx\x11\x96\xc7\x02\x1a\x97\xf55\xa3\x90\xe1g\xe9b\xa3\x88\xd1\xcb(\x96\xb4\x19\xffU\x19\x04\x92>\xe0\xd9\xd7\xfa\x9dg-\xaa1\x05 3\x8a%m\x06\x81.\xe9\xed\xaf\xa1\xc5[\x8d\x82\x86\x9d\x8f\xe3w\x1a\x85\x8cb@\xd2\xfe\xa4\xed\xa8e\xbdj\x86\x1cP\xb8,\xf3\x1f\x89\xff\xda(\n0\x15\x90\xb4?YHV\x9aڌ\xa2F0[c\x17\xb7\x19\xc5\x00\xe6\x02\x92\x06\x80\xa0\x02$\r\x00A\x05H\x1a\x00\x82\n\x904\x00\x04\x15 i\x00\b*\xfe?\xb6^u\v\xa5[\x1f\x81\x00\x00\x00\x00IEND\xaeB`\x82", - "analysis/ident-func.png": "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x03\xd2\x00\x00\x00\xda\b\x03\x00\x00\x00}\xf6\x8a\x1c\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x02\xfdPLTE\x00\x01\x00\x01\x04\x00\x02\x05\x01\n\x03\x01\x05\b\x03\t\f\b\t\x0f\x11\x0e\x10\f\x10\x12\x0f\x13\x15\x12\x15\x16\x14\x0f\x17&\x19\x18\x11\x1a\x1a\x13\x1a\x1c\x19\x1c\x1c\x16\x13\x1e7 \x1f\x19!# $$\x1d#$\"$%#'(&)(\"+)\x1e\x14+N++$*,)/-\"-.,.2402/63(241:7+685;9-:;9?<0=?=C@4AB@CEBGE8KH<MI8HIG\x00f\x00\x00i\x01JLI\x00j\x02SN=MOL\x05m\x051S\x96WRAQSP\fo\t\x0fq\vUVT\fr\x175[\xa4XZW,`\xae7]\xad\x15w\x1cb]K\\^[9a\xab\x19y\x1e;c\xad=d\xae`b_)z!?f\xb0)|*Bh\xb3egdLi\xafDl\xb0qjRikh/\x82/Ho\xb3/\x859Jq\xb6mol;\x86:Ut\xb4Xv\xb6?\x8a>|u]tvsB\x8c@@\x8dG\\z\xbby{x]~\xb7e|\xb8\x84|dK\x90J_\x80\xba}\u007f|O\x93Nb\x83\xbd\x8b\x81cN\x95Ud\x85\xbf\x81\x83\x80W\x95Vl\x87\xbc\x8f\x86hZ\x98Yo\x89\xbe\\\x9a[\x87\x89\x86\x93\x89k^\x9d]\\\x9dds\x8dË\x8d\x8a\x96\x8doz\x8e\xbfe\x9ef\x8d\x8f\x8c|\x90\xc1\x9b\x91s\x90\x92\x8fi\xa2i~\x93\xc4x\x95Ā\x94œ\x94\x91{\x98\xc7s\xa4l\xa0\x96xq\xa5s\x97\x99\x96\x83\x9bţ\x99{\x99\x9b\x98u\xaaw\xa7\x9d~\x87\x9fɜ\x9e\x9b\u007f\xabz\x89\xa1˫\xa0\x82\x9f\xa1\x9e\x8f\xa2ǡ\xa3\xa0\xa2\xa4\xa1\x92\xa5ʂ\xb1\x85\xa5\xa7\xa4\x94\xa8ͳ\xa7\x82\x8b\xb3\x89\xa7\xa9\xa6\x96\xaa϶\xa9\x84\x8e\xb6\x8c\x9d\xac̪\xac\xa9\x8d\xb8\x93\xba\xad\x88\x9f\xafέ\xaf\xac\xa1\xb1ѯ\xb1\xae\x97\xbb\x97\xc0\xb3\x8e\xa5\xb4Ԛ\xbe\x9a\xb3\xb5\xb2\xab\xb7ѵ\xb7\xb4\xa3\xbf\x9d\xa2\xc0\xa4Ÿ\x93\xb7\xb9\xb6\xae\xbaԹ\xbb\xb8\xb0\xbc֦Ũ\xbb\xbd\xba\xb2\xbdض\xbeӽ\xbf\xbc\xa8ǫ\xafƫ\xcd\xc0\x9a\xb9\xc0տ\xc1\xbe\xba\xc2ײɮ\xc2\xc4\xc1\xbc\xc4ٲ̷\xd2Š\xc4\xc6\xc3\xd5ƚ\xc0\xc8ݻ\xca\xde\xc7\xc9ƻκ\xd8ɝ\xc0\xcc\xda\xc7\xcb\xdb\xca\xccɿҾ\xc9\xcd\xdd\xd7ϡ\xcd\xcf\xcc\xc4\xd0\xde\xdfϣ\xc8\xd3\xc1\xcc\xd0\xe0\xcf\xd1\xce\xe1Ҧ\xc9\xd7\xcb\xd2\xd4\xd1\xd2\xd3\xdd\xdf֨\xcd\xd6\xde\xcc\xda\xce\xe6֪\xd6\xd8\xd5\xd0\xd9\xe1\xd8\xd9\xe3\xd5\xdc\xd1\xd3\xdc\xe4\xda\xdc\xd9\xe6ݯ\xecܰ\xd5\xdf\xda\xdc\xdc\xe7\xdc\xde\xdb\xda\xdf\xe2\xd7\xe1\xdc\xe0\xde\xe2\xde\xe0\xdd\xf0\xe0\xb3\xdf\xe1\xde\xdd\xe3\xe5\xe1\xe3\xdf\xe3\xe5\xe2\xe1\xe6\xe9\xe8\xe5\xea\xe5\xe7\xe4\xe4\xe9\xeb\xe7\xe9\xe6\xf1\xf3\xf0\xfa\xfc\xf9\xfe\xff\xfcd\x82\x05\xe8\x00\x00 \x00IDATx^\xed\x9d\x0fT\x14\xd7\xdd\xf7\x1fZ\xf3\xc6\xe6M\xda\xd7Q\xf6\xe9S\xe2K\xa9%F\xdbd\x95x\xdeJ\xa0fN\\@\x13\x90*\x82Ę*M\xa2\xb4Q⟜h0\xc4\x1c\xff\xb4.\xc1@\f\th\"I\xa4\xc1\x83A\xa4V\xadx\fA\x03\x96'\xc1D\x92\x87\xa4\xa6nj$QL#\t\x1c\x16\x02\xb7\xf5\xbc\xf7ޙ\x9d\xb93;\xb3\xb3\xc0\xee\x0e\f\xbf\xcf\xd1ݻw\u007f\xf7\xcfܹ\u07fd\u007ff\x98\xdf\u007f\\\x1b<\b\x00\x80\xe1\xc6\u007f\x18\xe9\xd6\aFy\x03\x00\x10r@\xd2\x00`)@\xd2\x00`)@\xd2\x00`)@\xd2\x00\x10`\xfa\x8c\f\x82\nH\x1a\x00\x02\x89+c\x127\xc7\xc8(\x98X^\xd2e3یL̤}f\x99\x91\xc9Hd\x14\xb7\xfaԩ\xce\xcaO\x8c\x8c\x82\x89\x89\x92n\xdeWTrB\f79\xcb}\xda~\xb3y^bN\xbfO\x13m\x9e\xe4\xd6\x19\x99\x04\x8as9I\xa9\xb9\xa7R\xbfR\xc7\u007f\xee\xe0\xefӲ\x17xr\xc2\x06\xaf\xb8\"\x0e\x135\xfb\xa4\x869Ck87\xd5_[?!\x99\xadC\xeb\xf0k\x81\x0f+\xa1`_\x04\xbeիxLr\xce\xfbFv~\xa2\xd5ꁡ\x81\xdbgd\x12dL\x93\xb4\xbb\xd2y\xb4\xf5\xa4\xb3\x85~h/8\\\xec\xd3\xfa\x91Ԋ\xbc\xa4\x0e\x9f&\x9al\x9dPdd\x12(\xea\x93~Sqp)\xcf\u007f\xa4\xfe\xa2\xff\x9d\xcd\x0e\xad\x04\"\xe5\xe1[\xd5QW\x8b\xb8\r\xd5E3\xb9j-{\x99\xa3\x196\xbfm}S-\xfe\"\x90\xcc\xdaPۓ\\\xd1U_\xe6\xb4`\x1f\x04\xa1ջ\xab\xf8\x97NUe\xddu\xca\xc8\xd0\x17\xa7\xceJA\x8dV\x0f\f\xb5\\\x8d\x91I\x901Mҕ\x05.\x84ڜ\xcd\xf4Cy\xa5˧\xa4;\xf8\n\xd4\xdf\xed\xcbB\x9bV\xdbr\xdf\x06mq\x81\x9a v$\xaf\xe9\xc5=/\xd3[\xd2\b\x95\xfa\x924Zis\xa9\xa3\x9a\xe8O\xfd\xcc)\x1a\xd6,\xebl\xfe\xdb\xfadF\x8a\x18\x102\xab\xe6\x9a|Y\x8b\x05\xeb\x12\x94V?\xc7\xd7\xe3_\xc7\xecL#;_d\xad\x97\xc3\x1a\xad\x1e\x10j\xb9\xa3F&A\xc6,I\xbb\x9c\r\xe4M\x18\f\x9a\x8aܾ%}\x81?\xee\xebk]2&u\xfa6h2\xea\xbc~S\x98t\x99\xbc\xed\xe5?\xf5\xfeη\xa4;'e\xa8\xa3\x04em\xe5\fj\xcfH\xda\xd0\xd6'\xd3\x03*頴:\x954\xaa\xe0\a\xf1\xc3.\xb1\x94\x91\xb4F\xab\a\x84\xd1+\xe9\xa3\x05=R\xf8jA\v\xf2!\xe9\xdey<%\x1f\xa1m<\u007fP\\\x9bn\xe3\x1d\x15\xf9\x99I9_P\x9b\v\xeb\xe79RŰ\x8c{\xa24\\\xb4\xa4D\x85O\x9a\xad\xfca\xde:\xa5\xbc\x99k.\x9f\xe2\xc4\xe1ƜtǼ\x9ct\xb2\\\xef\xaf\xcaJ\xca\xcc\xc7]\xe7C\a\xcf0\x97\x9e\x98\xf3\xedA\\~)*\xe5I\xf9\x9a\x06(s\vͳc/\x1e\xab\xfb+\xb2\x92\x96VХ\xff\x17\xb9i\xc9녉\xb7\x94\f\xa9\xea\xbb2\u008d\x94\bʚ\x1fM?\x14ό\x98\xb2\x8c\x88\xe4j\xca$[\xf4\x1c\xfaS\x88\\\xf3'E\xa6dȒVۢ\xce\xe5S'\xc6\x1d\x8dއ\x96p\x13\x8a\xf1\xc0).\u007fe\x83\x9aY\xd1\xe1Q\xb3q\xb2rN`:RIڠ`٠!\x9c\xe3V\xb6̟\x1c1\x9b\x9cTO\xab+c%\xe4Vg\x9a\x8f\x9c\xcd-i\xc9k.P\x13\xad\xb3)H:7\x8d\x84\x99\x96\xec.\xbc/)\xfb\x9d\xb4z\xb6k(\f\xa4\x13{\\\xe8E|\x96\x98\xa1w\xabk\x1e\x90\xf2(\x9c\xd3#\xa6\x93\xee\xa2sl\x88\xb4\xddh\x95tYy\xf3ng\xf1aڪ\xe5\x95ȗ\xa4\xd1G\x8d\a\xf9\xd2\xc6F<\n~\xd1\xe8(\x15צ\xe7\x0e:\xf8\xd4\xd2W\x92\xe9\x0f賓\xacW\xeaK\xf9\xbd\xaa\x84'\xa5\x15f\xf5\xc4\xe9OV\xae\xe36)\xbev\xcd\xe7\xa6r\xb7s)X\xe8\xefߕw\xa4\xbeb\x1e\xff-\x8e\xde\xc2\xe7\xd7W\xa4.\xedG\xbd\a\x0f\xa6gޓ\x96\x9f{\xd7\xe7ݍ\xc9/|\x85\xbez!\xb9\xb1[۠\x97-<ϱ\xb3~\xa7#\x0f\x87.$gV\x1d\xcfᩤ\xa5d\xea\xfa\x1e\xf6\xea\x05M\\\xb9\xbby9G\xb7p2&,)\xdf\x1a5\xbd\x8fh/\xa3\xbad΄Z\x1c\xd92qJQ\xd9,Φk\xdb>9\xea\xc9\xf2%\x1c\xe7D\xae\x9a\xf0u\xd2\xf2W6\xa8\xe5\xe6\xef\xaetFq=\xa8\xf3p͔\xb8\x9a\x9a\x9af13\xb7{\x1f\x95\xb4Q\xc1\xb2\x81\xbb\xa48z\xca\xc4\xe8e\xf39\xb2\xd5\xebiue\xac\x84\xdc\xeaL\U000d1cd9^Z\x9a\x9et\x0e\xe9\x9cM,\xe9\xeeO\v\xf1\xef*b[\xb2#=yo=Vs\x05\xdb5X\x03\xf9\xc4v76ff766zfQޭ\xaey@\x8a\xa3Ȱ\xad,_i\x9b\xaf{l=m\xd53\"\x872]\n\x04fI\xba\xc4Y\xdc\xe0j..\xc1\x9an.\xea\xf4-iv\xe2\xed \xe7T\x98\xc8:\x92\xf1\xefx^*\x0e\xf5\xa6\xe7\u0c71\xf7\xa0z\xff\xac\x9ck\x15\x02\xee\xe8\xd9nr\x1e\xdaU\x06\xfb¹p\xbaAY\x91J\xc4\\\x91\x8c;\xc1q\xbe\n\aϒ\xe1\x18O\xd5\xf8G\xba\x85U\xfc\x96\\\xfc\x92K\x86bM\x83\xcf\xf9\xbfH\xb9\xd6\xd3\x01\x85\xbefg\xe2\xb4\xfdK\x1d\xcad\xaa\xfa\xba\xb8\xddHI\x13\x1d6\xe7\x93`9G\xb6\x9aj\xb9\x17I\xfdIo\xb9\x9d\\\xf4\x9c9\x19\a\xfb\xa6\xdbtm\xe7G\x92\x19\xc92\x8e\f)6\xb2\xfdL\xe7ʌ\x813\x8a\x8c/[#iy\xcc\xc4[\xa0ɏ\x82\x19\x03\x9c\x037몸\x8e\x92Z]\x11\xcb \xb5:۾\x8e\xf4n\xa2\xd0,\xbd\xb3y\x8e\x0e\xb1y\xe4\a\x91i\xc9<\xd2\aP>\x964\xdb5\x18\x03\xe6\xc4*'\xde\x1a\xad\xaew@Rp\x1f\x9d\xc3\b\xaf\x9a\xc76\a7\x9d\xefK7!\xc0,I\x97\x17\x90\xc6\xe8,\xaaE\x9d\x05\xcd}}}\x9f\x14\xfb\xba\xe5F[\xd2y\x9e`\xbd֞\x14\xa6\xccӹʹ\x06\x8d\xafۗ٢\xb9I\xb6eX\xe8\x97\xd3\xd2\xf3+>\xea\xc7]\t\xe5\xa6\xf7~\x8bI\xa3\x13饎\xcfE\xe3S\x89ݨ;锞A\xafC\x1eT\xb6\b\u05ec\xee\xdbL\xb7\xf50;\x1d\xcad\xaa\xfa\xba\x84N\xc4\xd0\xc4m:Z>3\x82\xd4>e\xb2\xbb\a\x13MV~m\xceٓ'r\xb7\xe3\x9aS\xa9\xa2\x956]\xdb\bz\x15\xa9Y%i\xc6\xc05i\xf2\x12g\x03\x12&\x9f\x8c\xa47\xd5\xd6\xd6n\"\x926,\x985@\xd3m\xd2pU\xc6HZ\x8e\x95`Z\x9dm_G!y\xad\xe0;t\xce\xe69\xfe\x95\xb3dz\x12\x89\xb9ܒ\xfdI\xa5\xc2wJI3M͜X/I\xab[]\uf024`\xc6\xed\xf4m\xaa\xda@\xe2\x93}Ω\xa3v\x94\xae\x16~\"\xab\xcbP\xabӃ\xfe\x16\xa4\xb6\xa4\xa5\xe0^\xbeW3\xd9Q\xcf\xdcj+\xe7\xbdnB\xe8\xc9('^\xd5m\x8d\"s֎\x8a\xf5\x99\xfc\xbc\x97\xfa\xc9\xc0!\xb0\x86\x98,\xf5\xac\xbcз\xc9GБy\xe4\xc7^\xdb@\\K\xf7\xe2\xa1\xf9a\xfa\r\xca\xc9\xc2\x03E#\t\xd1J2\xc9T\xf5\xad\xe5\x0e#%tI\xdb>\x81\xc8g\xba8n\xe2!\xb2vR\xf4\xf2\xdd5q\xb8_\x9d\x10\xae\x94\xc8\xdbcj[q\b\xba\xaa\x924\x93\x19jw\xa6L增\xa4\xe5im\x8f\x19\x16\xccf\x86\xa6ϐ*\u007fT\x9e\xd12\xb1\x12l\xab3\xedK\xcf&j\xe4\xcf\xea\x9cM\xba\x96\x16~\"\xe5\x96\xfc\x82?B\xbe\xebVI\x9a=C\xf2\x89UIڻ\xd5\xf5\x0eH\nΜM\xdff\xcfP\x19\xb0\xd4p\xb5\x9a\xf1\xa1\xc3,I\x9f,\xa2\xa3r%\x9e\xa6\xb4\x11\x9a\x8a\xda|\\\xd8PIz\xa7Jҧ\xf8\x0f5\x93u\xda\xc4;\x1e*9\xcd[1\xdct\uf568\xfdl!Y\x98\x1dL\xac ?\xf1g)t\xde\xc7t\x82\xfc5h}>\th\x1b\x14&\xd2\xcf\a\xf9\xaf\xd0\x16a\x97-=\x0f}#\x8c\xd2y\x0ee2U}\xd7\xd9\xd4SSAY\x13I\xed\xe7O>I\xc1\xad3u&\xa9j\x8a<X2\xdbc*\xdb>a\x94n\x92%M\aV&\xb3\x13d\x0f\xeb\xea\x8b\x114#*\xe9\x82O\x14\x926,\x981`~\x14\x98VW\xc4\xcaȭζ\xaf\x83\xb6-\xd9\xd1\xd6>\x9b\xc2\xf6X29\xe7rK\x8a\xa3\xf4G\xb2\xa4w\xaa\x9a\x9a9\xb1biU\xe2\xbc\xc0\xbb\xd5\xf5\x0eH\nfL\xa6o\x933T\x06,\xa3wǻ\x9d^ĺZ\xe0\xb9}\xccߵt\x12\x9e\x9f\xf5\xffF%\xe9\xee\xd4l\xf2Þ\x9f\xafN\x972E\x98\xcewN\x8a#]h\xc92\xb5\x81+R\x98\x1a\x94\xd2\x0e\x83\xb27\x93Y1]$\x17\xbeD^\x19I\xbf\x9bx9\xf1]\x12\xd06\xe8H^O\xf6\xba\xb3\xd3=\x06\aI\x96Y\xe9\xb8[}\x9a\xe8P&Sַo\xeal\xa4BP֤e\r\xeb\xf0ʭ\x84ĬăZ4\xe9D}\xd3\xc9\xecoF4\x9e\xb7\xb6\xd8l\xba\xb6)Q\xa4cΧ\n\x8c\xc0\xea\xed\x9bAl\x19\x83u\u008a0n\t}\x8dÿ\xac\xe4;F҆\x053\x06\xca\x0e\xeeiu\xddn\xefiu\x85\xa4\xe7\xe1\xb5twz\xb6\xbauZ7\b\xd3xAҩ\xf9\xe7Jٖ\\?\x0f\xb7o\u007f\x1e\x95\xb4\xdc5\x18\x03\xe6\xc4\xe2W\x9c\xfbW\xc2wZ\xad\xaew@R\xb0\x9c\xce\xd5_\x14\x96\xcb i5'\nN\xb8\x9a\x8aw\xf7\xd0\x0f}\xae\xa6\"\x97z\xefJB\xd8\xf1~\x87Ν\x1eN}\xa94\x8bwT\x9d\xbb\xdc\xe8\xd8\xfcN\xff\xfb\x9b\x1dd'\xfcT\xe2}\x15\xf5\xc2&\x89\x82\x96\t\xe2\x1ew\xb5m\xaa\xb3|\x89\xfem\x8e\xa5|R\xe9\xf1#[x\xb2V.\xbc+\xf7\xc8_\xb6\xe03\xff\xed\xbbt\x8fT\xfcU\xefO\xcbI\xa3U\xd01\xa8Oz\xb8\xeax\x8e\x83̴s\xf9\xc2\xe3\x85<\xd9O;\x97\x94V\xba3\x99ԗI\xa6\xaa\xef&\xef)\x84pWa\xdcl\xb2x[Υ\x94\x94ep\xc5D\x85)\xce\r\xd3\xf1d\xf9(j\x8a\x88^\xb72rBxQ\xb3\x8e\xadkR\xb4s\xf7\x1c\x1b\x95\xf4̨\r\x1bfr\xc4V\x91\xd9\xc4u\xe5\xbb3\x84\xdd\xe9u\xb6Me\xb3\"\\ʻnj\n\x96\rz\x8e\xd2=s\xcf\x12ZluU\xac7\x8a\xe6s\xf0Y\a+2\x93\xc9~\xb4\xa2u\xe6p\x82\xf4\x04Ig\xe7l^ʶ\xe4\xe5\xd4\xf4\x8a#k\x12\xa9\xad\xd45X\x03\xf6\xc4\xe2\xdf\xff\xbdG\x1e\x11\xee\x1f\xd0ju\xcd\x03R\x1c\xc5\xfc\t\xcb˗O\x98\xef\xeb\xd8Nx\xcd\xe7C\x8di\x92F-eE\xbbO\b\x8aF.\xb2\x94\xd6\x1b\xa7{\x93\xe9\xc2\xc8A\xaf>\\\xc8N\xbc'g'\xcfo\xdbF\xa2>J¯\xdbp\xf4\xa7\xeb\xd3\xee\xc9:\xe2\x9dv\xa5Ml\xe0\x96\x94\xe8\x893\xd4[\x9c2U٥\xe9\x8e\xd4l\xe1v\xc3\xfa\xecy\xc9ٸ\x03}(\xac\xc8rD\x9b\xbd\xd2\x0e\x98\xb6\xc1\xb9\x9c\xa4yk\xe8\xceN\u007f\xc5R\xcfu\xe9\vk\x92\xd3\v\xab\x1c\xb4\x92\x9edHQߚ\b\xaf\xb9C\t^\xd0\xe1EnÔ(2\x1e싋\x8a\x9cId۷i\x8a-*\xa5h\x8a-\x0e\x1fϜ\xc8\xc9ˊ¹%:\xb6\xa8-#:b\xd6\t*閸\x88\x89\xb3\x96s\xdc\x12֠8n]t\xf8\xa48\xf1zӒȈ\xb8Z\xf6\x1eo\xa7a\xc1\x8cA\xc3\x04\xba\x06\x95\x86=\xa1\xd5ձ^(\x9aϑ\xbf%9-O\x90\x1b{6\x8b\xa2\xe8T\x9f\xdc\x18\xf0\nn\xe3\xccyd\xbe&\xb7dǖ\xf4\xc4G\xceRIK]\x835P\x9c\xd8\xde\xfc\xe4\xc4l\xe1\xa6P\x8dVG\x9a\a\xa4<\x8a\xad\xb7Gܾ\xd5+\x96\xa5-<\xa5\xa1\xcdԿ\xae4Oҡa\x99\xad\xc4\xc8\xc4\\^\xb4e\xf4\x18\xd9\f\x9aNa\xe9\x1br\x06\xd1\xea\xc2\xf6\xd8\xe0\xe8\xf6\x9e\x9f\x19\x10\xc4V/\x9b\xca\xc1\x1fW\x06\x95M\xd1\x03\xbf\x9f8\x84\xb4O\n֟\x04\x11̒\xf4 Z=\xa4\x92\x0en\xab\xb75\x04\xe7\xf6q?\xb1\xbc\xa4G5\xa6Iz\xe0\x84TҖ\x06$maZ\xf6q\xcb\xcc\xde\u007f\xf5\x8f/\xe8f\xa7\x91\x95\x0e\x17\xea\xf9\xfcw\a\x9b\xd8z\x80\xa4-\xccL\x8e\xe3\xc2[\x8c\xac\x86\x03t\xb3\xf3s48\xb2I\xe2\vFV\xa3\x06\x904\x00X\n\x904\x00X\n\x904\x00X\n\x904\x00X\n\x904\x00X\n\x904\x00X\n\x904\x00X\n\x904\x00X\n\x90\xb4i\x1c\xcf\xfa*\xb8\xae\\\x80Q\x89\x89\x92\xf68\xd0q\x17\xd1\xc7\x14\x15i=K\xc8¼ė\x92\x9b\x18\x83\xe7\xca\x05\x18\x9d\x98&iفN\xbb\xb3\xc1\x85\x19\xe8\x9f\xee\x8c<\x18\xff-\xe4\x91<UB h\xae\\\x80щi\x92\x96\x1d\xe8\xb4;\xbd\x1f\xb5hIX\xff-\x17\x84'b\x12\x82\xe5\xca\x05\x18\x9d\x98%iƁΨ\x914\xfb\x80\xca-\xa9\x92'\x98`\xb9r\x01F'fI\x9aq\xa0c\xa2\xa45<\xb5\xb0Nq4=\xb5\xf8a\xab\xe5\x8dG\u9fe5\xf7\x1ei\x90\xd6v\xe5\x02\x00\x83\xc4,I3\x0etڝ\x958XcB\xb7\xd6\xf2\xd4\xc2xu\xd1\xf6\xd4bl\xab\xe9\x8dG\xe9\xbf\xe5}\xe1\x01\xdf\x02\x1a\xae\\\x00`\xb0\x98%iƁ\xceU\x1a,y1\xe4\x9a\xd6\xf3\xbb#yu\xd1\xf1\xd4bd\xab\xeb\x8dG\x9ex׳\x0e.\xbd]\xb9\x00\xc0\xa01KҲ\x03\x1d\x84\x9a\x88\x98\xddE!\x1f\xaa\xf4\xfc\xeeH^]t<\xb5\x18\xd8\xea{\xe3\x91%}\x84g\xfe\xde\xdfە\v\x00\f\x1a\xb3$-;\xd0\xf1P\x13\xf2\xa1J\xcf\xef\x8e\xe4\xd5E\xc7S\x8b\x81\xad\xbe7\x1eY\xd2\xef\xf0\xef\xc8yx\xbbr\x01\x80Ac\x96\xa4\x19\a:\x95\x82\xaf\xbf\xear\x9f\t\x82\x80\x9e\xdf\x1dIz:\x9eZ\fl}{\xe3\x11\xfc\xb7t\xb3O\xcf\xf3v\xe5\x02\x00\x83\xc6,I3\x0et\xca\xe9\xf0\xdc^\xd4`\x90$\xe0h{jad\xaa\xe3\xa9\xc5\xc8V\xcf\x1b\x0f\xeb\xbfe}\xa6\xf4\xfc;\rW.\x000h̒4\xe3@\xc7\xe5\xdc\xd7\xf2ɉ\x82\x90\x0f\xd2ڞZ\x14^]\xb4=\xb5\x18\xd9jz\xe3AJ\xff-\x9f\x12\xdf\x11\x02Z\xae\\\x00`\xb0\x98&iƁN[eqQy\x93\x91}0\xd0\xf0Ԣt\x8a\xa3\xe9\xa9\xc5\xc8V\xd3\x1b\x0fR\xf8oA\xe8\x85D\xf12\x96\xb6+\x17\x00\x18$\xe6Iz$\x12\xc0g\xc0\xf7\xe7;\xe8\xd0\x1dDW.\xc0\xa8\x04$=\x10\x02(iԿ7\xad#خ\\\x80Q\bHz \x04R\xd2\x00\x10\x14@\xd2\x03\x00<\xb5\x00\xc3\x1f\x90\xf4\x00\x00O-\xc0\xf0\a$\r\x00\x96\x02$\r\x00\x96\x02$\r\x00\x96\x02$\r\x00\x96\x02$\r\x00\x96\x02$\r\x00\x96\x02$\rX\x95>#\x03k\x02\x92\x06,\x89+c\x127\xc7\xc8Ȓ\x80\xa4G\x1f\xd4s\xcf\xd0\x19\u07be\u007f\xa6NuV\x9a\xf6\xe4YS1Q\xd2\x1e\a:\xca`h\xa9\x8c\x92\xfeL\xbb}IT\xc4lS\xe6j\x9f;\xf8\xfb\x8cl\x10y\xae\x12\xe6\xae\xcc\n\xbf\xefH\xd5\xc9W\xf4\xdc\xd3>+\xf2I\x8do\a@\x80}\xff\x94G\xfa\xff'\xf3\x9e\xf3\x96\xc1q\\D\x8b\x86A\x03\xb7O#vT`\x9a\xa4e\a:l0ԔGHO<\x9b5ə\x11\xd1\xee\xcb8X\xf4\xbf\xb3\xd9ad\x83\xe9x\x89\xafj\xac\xcf\xe5_02\xf4\xa0\x9d\xaf\xc7sϲ\xc9ON\x18\xa2Ӣ\xc0\xfa\xfeY\xce-72\x91\xf0\x9c7WM\xcdV\xcdG&\xd7r5\x1a\xb1\xa3\x02\xd3$-;\xd0a\x83\xe6\xd1\xce\xe1\xee\xd9id\x15$J\xfd\x914\xaa\xe7\xcfa\x9dnc\x9f\x17l\x80F\xbe\x92\xe7\x9e\x19\x1bP\xc4P\xbb}@}\xff\xac\xe4V\x1a\x99hQ\xab#\xe9\x90?pv\xb8`\x96\xa4\x19\a:L\xd0DZ8\xff\xa7}\x01g\x00\x92F\xbd\xc9ی\f%4\xf2\x95<\xf7\xdc^\xe4\xe2\x86:1\n\xa8\xef\x9fu\xdc:#\x13-@\xd2*̒4\xe3@\x87\t\x86\x96\xf6\b\x8e\x9bPLB\xee(\x8e\xe2\xf5Ƞ\xe2\x99\x11S\x96ᱻ!\x9c\xe3V\xb6̟\x1c1\xbb\x87\t\xaa\x8c\xc5\xc7\x17\xb9&\n\x99q\x13UC\x98\x86\xbb\x1e\x84\xbe\xc8MK^/L\x90\x19\x17<\x9a\xb6\x82\xa4Ѷy\xba\xb6\xfd\x15YIK\x85ŶN\xbe\xb2\xe7\x9e\xd9+\xe7\u070e\x8f%\xbcY\xbb4\xff\x1c\tɾ\u007făW %c2S\xe4\xab\xe0I\x8e\xae\xed\xb5\x9bo\t\x17\xee\\6%b\x16\x89\x93\xcf\x1bA[\xbc\xd5 \xe9\xc1`\x94\xb7/\x18\a:L0Ĝ\xa8\xa9\xb1\t#CC͋ܺ\x9a\x1a\xf542c\u0092\xf2\xadQ\xd3\xfb\x90\xbb\xa48z\xca\xc4\xe8e\xf3\xb9O\x98\xa0\xcaZ|Ƞ\xbbh\xab\x80\xcac\xb6\x96\xbb\x1et!9\xb3\xeax\x0eO\xa5'\xbb\xe0Ѷ\x15%]\xc1w\xeb\xd9\xe69v\xd6\xeft\xe4\xe9\xe7\xcbx\xeeY7\xd1v\xa2gv\xdcQ\x9d\xd2\xfcs$$\xfb\xfe\x11\x0f^\x81\x94\x8c\xc9L\x91\xaf\x82\xad\x1c]\x99k7_sq8\x17\xb5n\xd3Dz]J>oHS\xd2=m\xd53\"\xcdZD\x99\x8eY\x92f\x1c\xe80\xc1\xd0\x13\xe1\xe9\x1aZ\x13\xefr\xae\b\x91>C\x9daL\xe7f]\x15\x97\aL\x90\xc5\xf3(\xe0\xb6V\x01\xe5擶\xbb\x9e\xecL\xac\xcf\xfe\xa5Dz\x8c\xb3\x1dm[Q\xd2\xc4\xf9\x8e\xb6m=}\xda0}\xd5Η\xf5ܳ\x81s\xa2\xab\x11䠇\xe0HH\xf6\xfd#?\aYB\xe9=ȓ\x99\"\xc8\xe2\xe4\x84q^\xbb\xf9\x90-\x12\xff\xe0Ώ\x12?E\xf8\x92\xf4\x1c<ƛ\xb8\x8c2\x19\xb3$\xcd8\xd0a}\xe9\x84\x1c\x9f\x92N\x99\xec\xee\xc1D\xd3\x05\xe3t\x9b4*3A\rZ9\x0f\x8aN\xae鮧C\xd0\xc6N\"=\xc6َ\xb6k\x1fQ\xd2U|\x87\x8e\xed\x16\xe1\x9a\xd5}\x9b\xf5\xf2e<\xf7\x94p\x91\xcbЦI=hH\x8e\x84|\xfa\xfeQz\x0frH\xa32\x13d)\xa2?\xa0z͇l\xe4,\xac\xb3\x89\x9f|J\xfa\x93}Ω0J\x0f\x06\xa3\xbc}\xc18\xd0\xf1\xf6\xa5\x13B|Jz\xbaط\xe8lo\xfa\f9^\x0ejQS.\xa0\xdcO\xd6t\xd7sV\x98\a\xd3m,\xc6َ\xb6k\x1fQ҅\xc9z\xb6\x0fS?=('K/_\xd9sO[IJj[\xebdz\xf4Cp$\xe4\xd3\xf7\x8f\xd2{\x90'3E\x90\xe5p\xa4\xa0M\xed\xe6Ct\xaaퟤ15\x9c)#\xc4p\xc0,I3\x0et\x98`\xe8\xf1)\xe9\xf9\x93OR\xe8\x14pz\x8a\x14\xcf\x04\xfdG\xd3]\xcf7\x826\xf2\x84\xd1Tr\xb6\xa3\xed\xdaG\xdc\xf1N]\xafg\xbbEpi\x9d\x9e\xa7\x97\xaf칧\f\x8f\x81s&O\xa4\xd7\xe1\x87\xe0Hȧ\xef\x1fo\xefA\x02Lp\x00\fLҰ\xe3=(\x8c\xf2\xf6\x05\xe3@\x87\t\x86\x1e\x9f\x92\xdeǕ\x90\xb7\x95\xf4&)cIk,'\x19\xb4\xdd\xf5d\xa5\xe3\x0e\xffi\"\x91\x1e\xe3lG\xdbV\x90t!\x11\xa0\xb6\xad\x10{\x90\xac\xa5\xb5\xf3E\x92\xe7\x9e\xdd\\\vj\xe0RP_t\xeb\x10\x1c\t1\xbe\u007fZ\xd7y]\x11S\x14\f\x92\x0e\x15fI\x9aq\xa0\xc3\x06C\x8a\xfbhM\x8d-\xa3\xa6\xe6\xaag\xc7۫\x17,\xe7RJ\xca2\xb8b\xd4s\xb4fJ\\M\r\xe9\xecLP\x85֦/\x83\x96\xbb\x1et.)\xadtg2\xef\xa8:\xa7p\xb6\xa3e+\xdc=\x96\xc7\xd3qR\xdb6\x97/<^\xc8\xe7\xea\xe7+y\xeei\x8bH\xd9\x1d=ŶdCx\xdb\x10\x1c\t1\xbe\u007f\xe6p3\x91\x1a)\x19\x93\x99\"_\x05\xe5\x13}\xcc\xd3\\5\xe1\x19G\xd1Ɍ\xf0\x1a\x17{\xde\xe8\xddc[kj\xbc\xf66N\x8c^o\xa0\xa6I\x9aq\xa0\xc3\x06CI\xed\x04a\xa9\xecD\xeeH\x1a\b\xf7\xba\x81m_\\T\xe4\xcc}X\xf2\x82)\xe9\xecLP\x85֥Y\x16\rw=\b]X\x93\x9c^X\xe5\xe0\xc9\xfd#\x8c\xb3\x1d\r[z\x8f7\x9f.Ny5m\xfb+\x96z\xaeK\xeb\xe4+y\uea5c\x12\xb5\xa4\xb3rJ\xa4S\xa74\u007f\x1c\t\xb1\xbe\u007f\xb6ڢ\x90\x17\x9edLf\xca|Y\xf6E\xf9\xb8-{\t9=M\x11\xf8u\ts\xde\xe8=\xde\x04\xafiS[xJC\x9b)w웎y\x92\x06\x82B_\xfbU\xdfW\x03=\x9e{\x86\x82\xb0=\xa6\xf4\xfd3'N\xcf\xda\x14ʦr\xf0Ǖ\x03\xc6(o \xf4\xb8&\x8d\x193\xc5\xe5SԂ\xe7\x9e!A%\xad\xf4\xfd\xb3a\xd8]\tnk\b\xe0\r\xe8#\b\x90\xf4\x88\x81\xf7\x83_\xfe\xd7\xff*.\x18\xf3_\xbf\xd4\xfe֨\x04\xbf\xf1v$\xe4\x8aڪi\t\x84\x1c\x90\xf4\x88A[\xa6J~\xf9\xbf\xe7\\\xbb\xf6\u007f\xff\xcf\xff\xd3\xfe֨\x04\u007f\x01GB\xc3\x19\x90\xb4\xa5\xe8\x8cL\xb9v-\xf2\xf6\x96\xe0\xde\\\v\x8e\x84\x863 iKA%=\xf1\xf6\xe6\xe0J\x1a\x18\u0380\xa4-\x85 i[ܬ&\x10\xf5h\x05$m)\x04I\x8f\x8d\xfc\xfe\r\r\xbb\xcb\xdbC\u007f\xa9\x1f0\x1f\x90\xb4\xa5\xa0\x92\x9e\xd4~\xad\xe7;aaa\xb6\xa3\xaeNP\xf5\xa8\x03$m%\xfa\xae\x12I\xcf\xc6\xe7\xe6\xfbs\xdc-c\xc3¾\xef\xec\x1c\x9d\xb7P\x8db@\xd2\x16\xa2u\xe6\xf4뱤\xb7\xe2s3\xab\xf9ڵ\x8ce\x87g\x86ŵ\x83\xa6G\x17 i\xeb\xe0\x9e\xf8\xfd\x19\xd7aI\xd7\xe2s\xb3\xfc_X\xdamxĎ\b\xf2\x05-`\xb8\x01\x92\xb6\x0e\raG\xafE`I#|nN\xe0\xffG\xf1\xff\x14[è}\xbc\xc7(\x05$m\x19\xfa6\x85\xfd\xeb\x1aYK\x13\xfe-\xfe\aI\x8f:L\x94\xb4\xe85\xa7\xa7\xd8)P\x8c\x80\xa1г\xe4\xfb\u05eeMJ\xb9\xd6\xe7\xfe\xf7\xb5\x1e\xfcߍ\xff\x13I\x87\x01\xc3\x17\xa3\x93:\bL\x93\xb4\xe45\xc7\xed<\xe9\u009c\x10\x1e\xd0oe\xaaO\xa2`\xe2\x9eo\xbbvm\xfa\x92\u007f\xff\xeb\xda\xc9\u007f\xfd\xfbZCߵk͂\xa4\xbb\x80እ$-{͡7:\xb9\x8b\xad\xff\x14\x8a\x19\x83yd\x99\xff\xb8\xe7D\xd2Ӳ\xf5I\u05f5M\x1b\xae^۰\x01\x81\xa4\x879V\x92\xb4\xdakNy\xe8\x9fS\x14r\x06\xf5\x14B\xffqϊ\xfe\xb7\x17 \xe9a\x8d\x95$\xad\xf2\x9a\xd3\xec\x1c\xa2\x13\xc5a\x84\xd2Î\xc7\x05O\xb9\xf8H\x9d\xe9\xe4\xa1;\x13\x8aQ\xab\x8d\x9b\xaa\xb0e]İ\xf8\xed\x85\xc6=sʿ\xbc\x98\x03\x92\x1e\xceXI\xd2*\xaf9%\x95>\xadG\x14\n\x0f;\x92\v\x9e\xce\xc3\xf4)\x845\xcd\xf4\xd1x\xeb\xf0\x8fZ\x86Ma\xabp\x11\xc3\xe0\xb7\x17\x1a\xf7\xccIȋ\xe8(\"\xe9gn4\xd4\xf5\xfd\xb7\x1aYx\x13F\xff\xe9\u007f\x190\xbc\xf2\xba\xf5~-3\xdf(2Q\x1d\xaeAe\x8d\xda\xef\x89\x1f|\x87\xbe\x87\xdd\xf8\x18y\xf3\xbfvV\x92\xb4\xd2kN\xab\xd3Zϔ\x91<\xec(]\xf0H\x13o\xf6\x01\xb6\xb27\x1e\xa5\x8b\x18\x11\xff\xbdи\x97\x8f\xa9\xb9\xaabwXJ\x13\xee\x8d\xe3^7\xea[\x17ǾE\xbb\x98\x91\x9d\x02}I\xbf>\xde8\xab\xb0\xb0\xb017\xdd\xf6\x94\x91\x19\xc1+\xaf\xb7\xc6^\x14\xbf\x19\\&\xe2\xe1j~\xa7Qq\xa3\xf6\xbb\xe1\xf9/\xe9\xfb\x97\xcf\xdfHޤ\xda\x19b%I+\xbd\xe6T\x96\xf8\xb6\x1eiH\x1ev\x94.x\xb4%-y\xe3Q\xba\x88\x11\xf1\xdf\vM_\xb3-\xec\xfa\x1bn\xb8\xe1{\xdf\xfb\xdeرc\xaf\xc7\\w]\x98\xad\xa4\xd5\xe7X\xea\u125fuu\xdd\xf1\xdb+aW~{\x87\x91\xa9\x8c~\xb6\xbf\xfa\x95\xeeW\x128\xf5\x95\xbf\xfe\xe1Ƿ^12\xd4*\xe8֧\xa4o\x06\x93\t9\\=4\x8eʨ\xfd¾\x14\x03_\n\x96\xb7\xfa\xf5\x1b\xd3e-I+\xbd\xe6\x14\x99\xf2X\xfe\xe0!y\xd8Q\xba\xe0і\xb4\xe4\x8dG\xf9\xf0y\x91\x01x\xa1q7\xad\x9c3+n\x96\xcc\xec\xd9K\xca\x1b\xda\xc3\xc8P\x16&vK\xa2\xef\xa7n\x1e3\xf6\x17\x1f\xe3\x0f\xcf\xde<\xe6\xa6DŽ\xbeu\xdb\x13X\x1b\x8f\xde\x12vˣX\x1c\xcf\xfeh̸\xfb\xbfԲ|t\xdcw\xc7\xd1\x14\x8f\xe1\xc0\xa3a\xaa\xfc\x1e\xfd\x81\x10\x89\x87\xb5?\x93o\u07bam옛\x9fb\x92ɦ]\x1e\x9d|y\v\x99\xa5zJ\xd4/H\xaeԃd\x16\xfc\xc4\x1dC\xca\x04\x1f\xee\xc7t(\xbd8\xf6c1\x1bO\xdd\xe8\xe5beq4\xe6\xadۮ\xbf\xee6\xb6-\xa4\xe2X\xc9\v!O픕\x16j.\xb5\x05\x8d\xf2:\x89C\xc7,I+\xbc\xe6\xb4;}\xb9\xa9\x18\x81H\xe2\xf5v\xc1S@\xc6d*ޕ6\xa5\xad\xb6\xa4\a\xe2\x85\xc6\xdd\xd6ڬ\xa0\xa5\xd5\xd5\xd9'\x8eҲ\xa4ǿ|\xf1\xbd;p\xa7{\xfe\x86g/\xbe\xf5\v\xa1\xef\x8d{K\x96\xf4\xeb?|\xfd\xe2[d=\xe8e\xf9̍/\xff\xe3\xe5\x1b\x9f\xc5\x11?x\xf5\xe2\xab7\x85)\xf3{\xd6\x13\xd9\xf5\xc6x\xfa\xcd\xcd\x0f\xfe\xfd\xca\xeb?g\x92I\xa6\x8c\x0e^\xff\xcf.\xb9D\xfd\x82\xe4J\xfd\xf4\xbfq\xaa\xb7\xc6\r)\x13r\xb8?#?6O\xfd̫Yh\x96\xca\xe2H\xd4\x0f_\xbe\xf8\x8f\xbb\xef\x96s\x97,\xf0\uf0b0\x92&|\x87N\xb9=\xb5S\xe5B^䶠Q\xde'qȘ%i\x85לVg\xbb\x81\xf9\bC\x92\xa9\xc2\x05O\\\x1cBm4\"b9\x9e'\xcf\xf0K\xd2\x03\xf3B\xd3\xe3V҃\u007f8\xbd$\xfd\x06~\xff\x9f\xb1]]?\xfe\x83\xd4\x13\xbb\xc6\\\x94'\u07b7\x10\x83\xf7\xc6iX\xfe\xf8\x19\xfc\xf2̏\xbb\xba~\xf2,\t\x84)\xf3\xa3\x91ϒrȼ\x1b\xbf_\xf7\x9e*\x99d*V\x85pqL\x97\\\xa2~Ar\xa5\xfe\xecI5\x84L\xc8\xe1\xfe\xe1\x16\xfc\xe1\x96?x\xb2\x91\xeaF\xb3T\x16\xe7\x19\x85\xffq\xa3\x9c\xbbd\xd1u\xe5\xb1\xf1]\x1e\xc6?F\x96\x00\x9eکr!/r[\xd0(\xad\x938D̒\xb4\xc2kN\xb3\xd3J\u007f-\xa4\xf0\xb0#\xb9\xe0AD\xad\x9b\xcafE\x90\x8d\xc0\x99Q\x1b6\xcc\xe4\u008b\x9a\x19[\xd6E\f\xcb\xc0\xbc\xd0h\xe0%iO`\xcc\xc7RO\xa4}\xdcc46L\x9c|zY^\xffw\xfc\xf2\xf7\xeb=\x810e~R$\x99w\x93\x88_\x8d\xbd\xfb\x89\xf7\xd8d\x92)\xf3F\xba\xbfT\xa2~Ar\xa5\xaexR\r!\x13r\xb8Wƾ\xd7\xf5\xde\xd8+\x9el\x94\xed\xa3,\x8eD\xfd\xf7\xcf\xc7*r\x97,\xf0T]\xfem\xfc\x03\x8d\xf1\xd4N\x95\xcb\x15\xb6RB\x94\xd1\xc9\x1b\x04\xa6I\x9a\xf5\x9a\xd3\xea\xf1;n\t\x94\x1ev<.x0\xee%\x91\x11qt?\xb0%.b\xe2\xac\xe5\x1c\xb7\x84\xb1e]\xc4(\x18\x90\x17\x1a\r\xc2\xf4$}=#\xe9q\xcc\x0e\xf0\x18qp\xf5\xb6\xf4S\xd2\u007f\x1e'&\xfe\xf3\x83\xb7]\xff\xa0\x81\xa4ɜY*Q\xbf U\xa54&\xde\x03Ʉ\x1e\xee\xdd\xf7w\xdd\u007f\xb7\x94\x8d\xb2}\x94ő\x97\x9f\xfc\xea\xbd//2m!Yt]\xf9-3J\xff\x96(\xd5S;\xef\\Tma-I\x03!B\xec\xa5c\xff\a\xbf\xbc\xc1\xf6ݟ0\x13o\xb2=\xe6\xe1Ǐ\x8a\x01/K퉷d\xe5\x99x\xd3\xfdnQl\u007f\xbd\x8e\x9dl2يo_\x92\xa5\xa6T\xa2~A\xaaJ\xa9\xb6\xc7\x06\x9a\t=\xdc\xd7\xc7w\x8d\u007f]\xcaF\xaa\xdbwȖ\x97\xb28\xf2r\x1d\x1e\xd8_e\xdb\xc2c\xa1\xb1\x96\xf6\xd4\xce;\x17U[\x80\xa4\x81A v\xd7;\xeex\xef\xe2\xcb\xe3پ\xfb\xea\x8d\xcfK\xdbc\xecU\x9d\x97\xaf\u007f\xe2\xe3\x8b/ߪa\xf9\xccMd\x9fI\xbd=\xe6\xb1zv\x1c\x8e\x1c\x87\x03\xe3\xdf\x10\"n}\xfe\xe2\xc5Gof\x92ɒ\x16\xd2]yO\xb8\xfe$\x95\xa8_\x90\xaaR\xf42\xd1\xe03\x11\x0ew\xfc\x83\x9e\xe1\x95=\x8cq\xcf{\xb5\x01y\xb9\xf9\xc1\x8bo\x8cg\xdaB\xb2\xe8\xf2\xa4\x95C\x9e\x8bX\u07b9\xa8\xda\x02$\r\f\x02\xb1\xbb~\xfc\x8b\xb1c~\xf4\x14\xdbw\xbb\x9e\xf9ј\x1f\x88\x17\xb1\x14\xf7^\xbc\xfa\xd3\xeb\xc6\xfc\xf4e-\xcbG\xc7}G\xbc,\xf4\x03\xf9\"\x96d\xf5\xe8M\xdf\x1d\xf7\xe0\x18a\xdeM\"\x9e\xffɘ\xb1?\xff+\x93L)ir\x97\xc8ϞR\x94\xa8_\x90\xb2R\xc2\xcd\x1c\x83\xcfD8\xdc\xfb\xbf\xeb\xb9͋=\x8cgƑկ\xa28\xf2\xf2\xc6\xcdcn\xfa-\xdb\x16Rq]\xea\xeb\xd2\xf2\xad&^\xb9\xa8\xda\x02$\r\f\x82\xb0.\u007f\x18\xcc\r\xa1Z\xe0\xd9,\x9dw\u007f9\xc6\xc8r(\xf8\u007f˥\x0e\x81:\\\x81\x9b\xa4\xbb\xc7n\"o\xfe\xd7\x0e$\r\f\x02\xff$\x1d\b~\xf1狯\xff\xf0Aa\x81\xfa\xfa\xcdF\xd6\x16≛\xc4{\xbcox\xcc\xc0R\x05H\x1a\x18\x04\xa1\x93\xf4\x13\xff9f\xfc\x83B0l\xfc\xab\xbem\x01\x02H\x1a\x18\x04\xa1\x9340P@\xd2\xc0 \x00I\x0f_@\xd2\xc0 \b\x03\x86/F'o\x10\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x8cfI\xa7pQ\U000db34c\x00`d1\x9a%\xed\xaa.\x9a\x1a\x05\xeee\x00ka\xa2\xa4E\a:\bu\x1e\xde]\xb0\xfb\xb0)ڪ\xe6,\xef\xe3\x03\x18e\x98&iɁ\x0ej/\xde\xdd\xecj\xde]lƓMj\xb9\xa3F&\x000\xa20MҲ\x03\x9d\x9a\x12\xf2 \x84\x9e\x92\x1a\xa3$A\x00$\rX\r\xb3$\xcd8Щ\x14\x9e\x12Zf\xc6\xd3\xf9AҀ\xd50KҌ\x03\x9d\xf6\xe2\xeavw{\x8d)\x13\xef\x06\xae\xda\xc8\x04\x00F\x14fI\x9au\xa0\x83\x97\xd5N\xe7>S\x9e(莚q\xd8\xd5gd\x05\x00#\a\xb3$\xcd8\xd0qW\x964\xbb\x9aK*Mq]\xb9O~\xf0\x1f\x00X\x01\xb3$\xcd8Щ\xa1\x8e\xb1\xdc%f8\x98\ue31a\xbc\xb5\xdab~\x01\x80эY\x92f\x1c\xe8\x14\b\x97\x86\x1b\n|\xd9\a\x89ZΌM9\x00\b\x1efI\x9aq\xa0#J\xfa\xa49\x92\x86\x1do\xc0Z\x98%iƁN\xb58\xf16c\xef\x19$\rX\r\xb3$\xcd8\xd0q\xbfX\xd2\xe4j*yь-\xef\xa3 i\xc0b\x98&iƁ\x8e\xbbvw\xd1\xee\xda\xd0+\xda\xed:\x99b\xb3\x96\xafz\x000O\xd2\xe63\x87\xe3\xa2ˌ\x8c\x00`d1\x9a%\xed:\tC4`9F\xb3\xa4\x01\xc0\x82\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x98(iɁN_CY\xc1\xee\xe1\xe3o\xee\\Nrr\xf6\xa9\xa5\x8dFv\x02\xf5\xa9\xc7\xf5\xbf,\xe5\x1d\xe4\xdb\xfa$\xbeT\xdb`\x1b\xcf\x1f\xd4\xfe\x06}\xee\xe0\xef\xd3\xf9*\xb0\x8c\x88J\x02~c\x9a\xa4e\a:\xa8\xbc\xe8d뉂\x13F)B\xc4Yǚ#\a\xd7\xeb\xf7b\x15Ǔ\x8e\xe8\u007fّ\x9b\xf4\b~{$1\xb7C\xf9ũ\xb3\xc2\xfb\x17\x8d\x0e\x1d\x1d\xa1\xfew6;t\xbe\n,#\xa2\x92\x80ߘ&iفNC\x01y(\u007fK\x81)~\xee\xbc\xc9\xc9\xee\xc7]u\xb3\xbf\x92F\xfd\xbe\xbe,\xccI\xea@\x1d\x899\x85\xaa\xf8\xac\xf5\x9e\x90\xaeZ\xf0\xf0\x19\"\xb5\x8c\x88J\x02\xfeb\x96\xa4\x19\a:\xe5\xfbhL\xf10\x19\xa6\xd3i\xcf>\xc7\xfb\x18|\"\x05\xd7\xcf\x00\x00\r\xafIDAT\xfd\xa70\xf7\x91\x83\xa8*'W\xad\x96\xa5\xc3I-#\xa2\x92\x80\xbf\x98%iƁ\xcen\xc1\xbf]Y\xb9\xaeqp\xf8\xd0\xc1\xf3;/\xe4\xa5'\xe6|\xcbF禞ï\xfd\xf5\xdd\xe4\xb5*+)3\xbf[a{\x90\xe7\U00062cd4'S\xf3\x8e$^\x9e\xa1_X?ϑ\x9a\xf3\x05\x9b\f\xab\xa5b=ʩ\xa0j\x91b\x8f\xf3\x02Y$\x95\xa30?3\x89\xa6B\xfd\x15YIK+\xe8\xa8\xffEnZ\xf2z՜\xd65\x91\x13\x98\xa8zr\x83\\\xb0\x84\xe2\xd8\xe4\xea\xa0\xee\xc2\xfb\x92\xb2\xdfI\xabW\xa4\x0fd%\x01\xd31KҌ\x03\x9d\xc3\xc5\xf4\t\xa1E\xbb\x8d\xd2\x04\x98ރ\a\xd33\xefI\xcbϽ\xebs6\xfa\xf3t>\xa7\xf4\xdd^\x1a\xde\xc2\xe7\xd7W\xa4.\xedgm\xbb\x1b\x93_\xf8\n}\xf5Br#\xee\xf8g\x1b\x1b\x13\xc5\x11\xecTR\xd6+\xf5\xa5\xfc^6\x19V\xcb\x17I\xdf$^\xa6j\x91b\xbb\x1b\x1b3\xb3\x1b\x1b\x1b?%\xc9\x1c|\xe6\xc1\xe3\xf3\xe8x\x98\xe7\xd8Y\xbfӑ\x87C\x17\x923\xab\x8e\xe7\xf0J\xb5\xb8\x8b\xb6\n\x14)\x1f\xd3\xc6\x14,\xa186\xb9:\x1d\xe9\xc9{\xeb\xb7\xf1|\x85\"\x83@V\x120\x1d\xb3$\xcd8\xd0\xe9,*os\xbbʜ%Fi\x02\xcfR\xfe\x91n\xd4߭\x8c\xec(\xfd\x8d\x83O&c\xefq\xbe\n\xbf\x9e\x15\xc6a\xd9vK.~\xc9\xdd\"\x9a\x8b\x92\xeeM\xcf\xe9%R\xeaP$+\xccEK7g!\xa2\x16ef\xf2\x9c6\xf5\x1b\x9cc*\x0e\xd5\xf3\xf5\x9e\xd7\xecL\\N\xffR\x95Z\xdaZ\x05\xda\x14\xb1L\xc1\n\xa4\xfa2\x05\xe7%\x93\x916\xdfK\xd2\x01\xac$`6fI\x9aq\xa0\x83\xda˝N\xe7\xd1r\x13\x9e\xec\xb7ԡ\x18\xa0%zO\xe5\x90N\x9b\x9b\xde\xfb-&m\x8b\xd2\xf6Tb7\xeaN:%~\x12%]\xcf\u007f\xe4I\xcd$\xc3jy\x85\u007f\x89\xaaE\x99\x99\xac\x16\xf2\x99.H\xb7\b\x97\x83\xeeی:\x04\xcd\xedT\xaa\xa5\x95\xf3\xa0\xf0\xf8\xc3\x14\xac@\xaa\xaf\\p\u007f\x12\xad\xeb9oI\a\xac\x92\x80\xe9\x98%iƁ\x0e\xc6\xddއ\x8aM\xf0\x89\xb54\xcb;\ueb30d|x\r\x19\xe8\x04\xd6(m\xbfM>\x82\x8e\xcc\xf3\xect\x8b\x92\xde\xcb\xf7z\xbeg\x92a\xb5t\x14~Eբ\xccL\xb9\xf3D\xd5\xf20\xfd\x06\xe5d\xe1Q\x92^\x14W\xef<Ք\v\xd4(b\x99\x82\x15H\xf5\x95\v\xfeB\xd8\xf3\xeb\xf6\x96t\xe0*\t\x98\x8dY\x92f\x1c\xe8 \xbaQ\xd6\xe24\xe1q\x9dr\xa7\x95Iͧo\x85\x99d\xcc:K\xe9P\xd9\xe6\xafA\xeb\xf3=\x1fDI\x9f\xe2?\xf4\xc40\xc9\ns\x85\x98B\xad̪\xc80*\xabeK:\xf9\x95\xe8O\xcfC\xdf\b\x9a\xcb\xf3K-L\xc1\n\xa4\xfa\xca\x05\x8b\xa3\xf4Gޒ\xa6vA\xac$\x10:̒4\xe3@\xa7ى\x17\x87W\x8b\xcd\xf0\x9f\xc3J\xbau\x830\x9f\x9d\x97F\xfas?\xf9\xaa^XS\x16\xbe\xa4\xb2}7\xf1r⻞\x0f\xa2\xa4\xbbS\xb3\xc9h\x99\x9f\xafHƨE\x91Yv6B_\xd1\bY-\x82\xc1A2\xe3\xcfJ\xc7u\xf84\xd1/\xb50\x05#\xf9(\x98\xfa2\x05\xaf\x9f\x87\xf3\xed\xcf\x13%\xed\xb1\rA%\x81\xd0a\x96\xa4\x19\a:-\xceZWCqyȽm|\xfb.\xdd\xd3\xf5\xac\x90\xe7\x88~\xa6\xe7\xf1\xa9\xa5\xf5G\x1eI\"[\xbd\x85w\xe5\x1e\xf9\xcb\x16܋\x95\xb6\xfdi9it\xde\xdd\xfbNcc\xe2\xe6F\xb2\xf7\x8dW\xd8\xf7U\xd4\v;OR\xb2or\xb3/\xe3ϗ\xb3s\xbfab\x11\x91\xc7^\\\xc4et\xb9ѱ\xf9\x9d\xfe\xf77;\x1a\xb1]._x\xbc\x90'\xfa:\x97\x94V\xba3\x99wT\x9dC\xc60\x05KG\xa1\xa8\xaf\\\xf0\xe5\xd4\xf4\x8a#k\x12\x95\xb6!\xa9$\x102L\x934\xe3@\xe7dIQ\xf9I#\xf3\xc0\xf3\xa1\xb0l\xcc\x11?\x16E9\xe9\xfbo*\n\xefKJ]C/ޠ\xfa\xecy\xc9\xd9\xf5^\xb6{\x1d\xc2%\xa3\xf7ť'\x95ȧ\xeb\xd3\xee\xc9:\xa2HV\xca\xf3dci3Oo\x9f\xf6\xc4bz\xf3\x93\x13\xb3\xcf\xd2ۧy\xc7G\xe4\xea\xf66r\xc9w\xa9\xe7\x92\xef\x855\xc9\xe9\x85U\x0e\x12k\fS\xb0\xe7(\x94\xf5\x95\v\xeeؒ\x9e\xf8\xc8YQҢmh*\t\x84\n\xf3$\r\x98\x85z{\f\xb0\x14 \xe9\xd1\aH\xdaҀ\xa4G\x1f iK\x03\x92\x1eu\\\xa8\xe7\xf3\xdf\xf5\xf9\xf7c\xc0H\x06$=\xea\xc8&\xbb]\x17\x8c\xac\x80\x91\nH\x1a\x00,\x05H\x1a\x00,\x05H\x1a\x00,\x05H\x1a\x00,\x05H\x1a\x00,\x05H\x1a\x00,\x05H\x1a\x00,\x05H\x1a\x00,\x05H\x1a\x00,\x85I\x92\xee)v\n\x14\x93O\xae\xb2\xa2}&<\xd3\x04\x00,\x88I\x92v;O\xba0'\xe8\xb3M\\\x055-5\x05\xa0i\x00\b\x00&I\x1a5\xd1gw\xd3G\b\xf6\xd1\xd7\xc3\xc5}\x06I\x00\x000\xc6,IS\xca\xc9s\x8aPs\x01\x95w\xc1\xf0\xf1]\t\x00#\x173%M\x9f#\x88P\xa5\xe0\x13\xab܌\xe7\t\x02\x80\xd50S\xd2%\x95\xf4m\xb7\xf0\x00\xef\xc3&<\x9a\x1f\x00,\x87\x89\x92n\x15\x9f\xdc]\\K\xdfj\x8b}\x19\x03\x00\xe0\x17&J\xbaRt\x82%z\xae\xac\x0e\xb5\x9b;\x00\xb0\"&J\xbaHt(])x\xa1-\x83\xb54\x00\f\x1d\xf3$\xdd\xee\x14\xfdB4;\x89ǻ\xabN\xd8\xf1\x06\x80\xa1c\x9e\xa4[\x9d\xedB\xa0\x8f\xfaΩ\x86\xeb\xd2\x00\x10\x00̓t\xb3\xd3\xe32\xc7UP\xddZ\rw\x8f\x01@ 0Oҭ\xf2v\x98k_A\x19(\x1a\x00\x02\x81y\x92\x06\x00 \b\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\xd1ڵZA\x00\x18\x99\x98$i\xa5\x03\x1d\x84\xaa\xcd{\xa4\xc9\xdf\xecOk\x04=\x1c\xb0c\x12p\xe0\x83_\xc7\xc7.:\xb6\xe0m\x1c\xdc>\xf7\xceiw\xce݁P\x9dݾ\b\xa1\xfd\xd8\xe2\x98:]\x908\x16\xff')|~\x9a\xfd^\x1f\xa6\xbeYk\xb7\xef7\xb2\x19\x10\x81k\xa8\xd5\xd8,漑\x15\xa0\x87I\x92V8\xd0A\xa8\xcdYk\x90 x\xac\x8a\xb9\xa4\x11\xf4\xe0~\xbb.v\xc5\a\b\x9d\x99\xf6Ё\xfd+\xa8\x0e\x8e\xd9\u007f\xbd\xe7\xd0k\x0f\xd9\xeb\x90\xfb\x98=\x06\xbf\xee\xb7\x1fs\xa3\x00s\xec\x8cf\xf4\xa1\x18F\x88\xa7W\xc7h\x1a\xf9å\xbai;\x8cl\x06D\xe0\x1a곺\xba=\xf6\xb7\x8d\xac\x00=L\x924\xeb@\a!W\x89y\x92>oߨ\x11d\x89'C\xf7\xe2\xc5$\xb8\x9a\xf4ԍ\xb1\xb4\xee\xb1\xd8\xd8m_\xb5\x9a\xa4\xf3\xa3\xa3\x0e\x90\x05+\x8c,0;\x06/i\x84b\x02+i\x14Ȇ:\r\x92\x1e<fI\x9a\"8\xd0A\xd5\xce\xea\x02\xd3$\xbdZ\x1e\x99W{\x0f\xd2\x04\xdaS\x13\xb6\x93\xe0\a\xf6\x03\xb8\xd3.\xa4\xd1\v\x17\x93\x9ez\fw[\xbf{\xea\x00\x18\xb1\x92\x0eHC\x81\xa4\x87\x80\x99\x92\x16\x1d\xe8 \xb7\xdb\xf3x\xfe\xd0s~\xdaF\x8d\xa0\x02\xdaSW\xc4\u007f@\u0087p\x9f\\$\xa8m\xc5\"\xd2S\xcf/د\xee\xa9g\xa6\xd9\xed\xdbϯJ\x88y\x80< q\xff\xa2\x98\xb9\x1b\xe9\xf7\xee\xa7\xef\x8d]\xf4v\xc2!\xf48\x99\x96J+a٠nq´\xf8_\xe3\xf5\xe8\x9f\xec\x02\v\x90\x82\xafc\xec\xd2\n\xf8Ҫ\xf8\xd8\x15\xde\x13\xef\xf3+\xe2q\x16\xf8\x97\xa9\x13\a\x12\x1e\"\xb3\xf7\xc7\xed\xd3\xf6l\x9c\x1b\xb3\xf83\x95i\xccƵ\xf1w>$\xacY\xe5:\xc8h\xe6p\b\xd7\xe0\xf7h\x87]s%>І\"k\xeb\x1dbfri\x04Q\xd2z\r\x85\xd0k\xf1{\x10\xa0\x8d\x99\x92\x16\x1d\xe8\x10L\x93\xf4\xdai\x9fi\x04\x15О\xfaY\x82\xfd\x81\x1d\xa7\xe9\xa4b\xc1\xefh\xf4\xef\x16О\xba\xeb\xd7\xea\x9e\xea\u07bf?anl\xc2\xc6U\xf6\xcf\xc8\ft\xe3\xa1]\xf1\v\xb0\xb8\xbfN\x88\xdfuh\xadݾG\\NJ+a\xd9\xe0\x8c}\xd5\xfec{\xe2\xed}d]:wQ]]\x9dz\x8f\xe8L]\x9d8\xb6\x9e\x8f\x9d\xfbڟ\x16\xdbՒ~3v\xc1s\xc7v\xd8w\x11\xed\xad}s\xffC\xf6\xd3\b\xfdm\xff4{\xfc\x8e]\xb1\xeaa?ƾ`\xff\xfe\x051D\x80r\x1d\x184sp\xbf\x9d\xb0\xf6\x12\xba\xb4=\xb6Nc\xbc\x1dpC\xd5\xc5n\xf7d&\x97F\x10%\xad\xd3P\x98\x15\xf6\a\x10\xa0\x8d\x89\x92\xf68\xd0!\x98%\xe9Ϧ\xad\xd5\b*\xa1=\x15}\xfd\xdc\xc2i\xf6X26ݻ\x8aF\xaf\xba\x97\xf6\xd4K1\x97\xbc\xe7\x93\v\xec\x8b;\xf18Gt\xf1GDz(N\xb7*\x96L\xeb7\xda\xc9\xf0B\x85I\xa7͌\xc1\x9ex\xd2]\xf7\xc4\n9\xe8L\xbcEI/\x9a\x8b\x8b\xec[\xa0\x92\xb4;\xe1\x01\x1cݳ\xffk\xf2\xbbB\xea$\xe4\x12\x13\x8b\u007f[Vūs\xba\x17[\xb8\xe7.Tԁ\xcdL;\x87\x1dd\xea@\x16\xc6\xde\f\xbc\xa1V\x93\xdc\u007fGڝ-\x8d\x99xk6\x14\xe6\xfcs\xb0%\xae\x87\x89\x92\xf68\xd0!\x98%\xe9ǧ\x9d\xd7\b*\x89\xf7\\\xd9r\x1f{\xc0~H\x1a|V\b\x83\x0f\xfa\xf5.\rILj\x03\xfe\x8a\x84\x9e>L\x02\x96@\f]d\xfeM%i\xc6\xe0\xb3\xf8\x84\xc7\xf7\x9cA=B\x0e>%\xfd5\xcd\x05mWI\xfa\x90]\xde'\xff\xe7\x9e\a\x12b\x85\xa9{\f\x11\xa0\u05fa;\xe6\xf7\xe4u\x8f\xfdk\xb6\x0e,\xda9|f\xff\x00\xb9c5\xafE\r\xbc\xa1ތq#wL\x1d\t2\xa5iJZ\xa7\x92\x80\x17&J\xda\xe3@\x87`\x92\xa4/Ŭ\xd5\b\xaa\xa0=\xf5\xb4\xb0s\xb6\xe8!\xe1?\xe6!a\x89\x88\xf6/А\xb4g\x15\xbc@\\\x15\xaf\xc0R8@\"\xdc*I\xcb\x06X\xa8{V\xdck\x8f\u007fNH\xe8S\xd2g\xecT\x06j\x99\xee\x92+r:>\xe1\xe9\x03u\x8b\x17Hi\xbc%Ms\xaaÿ\x02l\x1dd\xf4rx\xe0it,\xb6\ai0\xf0\x86\xea\x8b?\x80\x0e\xd0\xc9\t[\x9a\xa6\xa4\xb5+\txc\x9e\xa4%\a:\x04\x93$\xbd\xd1~^#(\xd1G\xa3hO\x8d\u007f\x9c\xc6l\x9f\x8b\x90\xd8\xef\x16,\x16z\xaa;昷\xa4=\x1doU\xc2\x19\xca?Q\x9f \xa1\x0fdI\xd31V6@gH9_\xef\x8f\xd9#\xe5\xf0\x9a\xf7\xe2^\xc8\xe5\x9f\xc2(\xad\xde\x1e;&\x8f\xd2\xf7.$uZ\xe1K\xd2\x1b\xc9\xebk\xf6N\xb6\x0e\fz9\xfc)\xbeg\xb5z\xa8\x1ctCm\\\x81Vl$\x01\xb64\xb5\xa4\xd5\r\x05\xf8\xc4<IK\x0et\b\xe6H\xfaR\xccj\x8d\xa0\xcc\x1e2\x18\xfe\x93\xec6\xa1\xf8\x84\xafI\fQ\x9ax\xb9\x95\x8cꤧ\xa2տӗ\xf41a\xed\xb7\xfd9\xb2\x15Lz\xe3*AҸ\xf3\xf7-\x8cQ\x1a\xec\x10n\xadZDg\v\x8b\xf0\xd0vIc[Y\\K/$\xd59\x1f\xa3\x92\xa9;~\x11\x19>7nD(\x81Ԡo\x81/I'\x90u\xf7\xbd\x8b\x14u`\xd0ˡ'\xfeOw\xaa\xe7݃n\xa8\xd31\x97b\xe8\x96\x18[\x1a+i\xad\x86\u009c\xdf\x01ki=̓\xb4\xec@\xc7\xedr\x15U\xbb\xda|Z\a\x85\xa7\xe5\x91\xf9i\x8dA\x9a\xdc\xfe\xb4\xff\x8f\v\xe3\xc9X\x19o\x8f\xdf~\xec\xc0br\xa3\xe21\xfb\x03\a\xea\x0e,\xc6\x13i7\xeegnT\x17\xa3\xec\xa9}\xa7\xe9~\xf5y1\xdf\xdf\xed?@o\xbc\xb8\x14\x9f\xb0\xe7\xc0\x8a\x18*\xe9E\xf1\xcf=\xb7\xd0>\xed\x8f\x1f\xb0\x06;\xec\xb1\xdb\x0f\xe1\xe0\x9b$ݎ\x98]\xb84\xe5(\xdd\xf3v]]\xcc꺺N<\xd8\xc7$\xec\xd8~\xa7\x90\x03ñ\x98{\xf7\x1c\xdah\u007f\x8dd\xb6b\xcfs\v\xf04\xfe\xf4\xa5\xbai\xabO\xa33\xab\xa7\xd5)\xaf\xba\xc7\xd8\x1f8}lQ,\xa9\xa6\\\a\x06\xdd\x1c\x9eN\x88U\xbb/\x1b\\C\x11\xe2\x17\v\xdbvri\xc2\xddc\xbb\xea\xeaHn\x9a\r\x85y\x88\xdc`\nhb\x9e\xa4e\a:'\x84۽\xaf\xfa\xb2\x0e\x06\x97bVi\x04Y\x0e,\x88\x89}\x88\xaaf\xe1k\xdb\uf349\x17.\xe3n\x9f\x1bk\x8f%\xb7.\xbfI/\xa9\xf6-\x8cWt\xf13¢OXH\xa2c\x8b\xe3c\x17\x1d\"\xa1\u007f\xaeN\x88Y|\x86J\xfa\xfc\xa2\x98\xd8ſ\xb7\xdbײ\x06\xfb\x17\xedH\x98\x16\xbf\x88*\x1a\xb97\xde\x19\xb3\xe84R f,\xe4\xf0Н\tO\xffq\x1á\xe1\xfc\x8a\x84\u0605d\xd1\u07b7knL\xfc\x8a\xd7\xe6N[\xb4\x16\xa7\x98\xf6\x01\xb9\xa4\xad\xb4\xbdwNJ\xd8\xf8U\x82\xcc\xe5J\xca\xe8\xe6p^](\x1adC\x11v\xc5\xec\xa2\xefri\xf4\x1eoϪY\xb3\xa1h2\xf5\x06>\xe0\xc1<I\x9b\xcf\xef\xed\u007f\xd3\b\x06\x17a{lD\xe3\x8ey\xd3\xc8$\xf8<\xb4\xd8\xc8b\xd42\x9a%m\xc6_UZ@\xd2\xfb\xbd\xc7ڐ\xf3\x9c]5\xa7\x00$F\xb3\xa4\xcd`\xa4KzǛh\xf1v#\xa3\xa0\xf3Y\xfc.#\x93\xd1\vH:\xa4\x9c?fߨZ!\x8f(\xdc\xf6\x05\x8f\xc7\u007fmd\x05\x98\tH:\xa4,\";M#\xf9\xfa\xcb\xf6\xd8\xc5#\xb9\xfa\xa3\x01\x904\x00X\n\x904\x00X\n\x904\x00X\x8a\xff\x0f\xb8\x98\xba\xeaw\xacpV\x00\x00\x00\x00IEND\xaeB`\x82", + "analysis/ident-func.png": "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x03\xd2\x00\x00\x00\xda\b\x03\x00\x00\x00}\xf6\x8a\x1c\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x02\xfdPLTE\x00\x01\x00\x01\x04\x00\x02\x05\x01\n\x03\x01\x05\b\x03\t\f\b\t\x0f\x11\x0e\x10\f\x10\x12\x0f\x13\x15\x12\x15\x16\x14\x0f\x17&\x19\x18\x11\x1a\x1a\x13\x1a\x1c\x19\x1c\x1c\x16\x13\x1e7 \x1f\x19!# $$\x1d#$\"$%#'(&)(\"+)\x1e\x14+N++$*,)/-\"-.,.2402/63(241:7+685;9-:;9?<0=?=C@4AB@CEBGE8KH<MI8HIG\x00f\x00\x00i\x01JLI\x00j\x02SN=MOL\x05m\x051S\x96WRAQSP\fo\t\x0fq\vUVT\fr\x175[\xa4XZW,`\xae7]\xad\x15w\x1cb]K\\^[9a\xab\x19y\x1e;c\xad=d\xae`b_)z!?f\xb0)|*Bh\xb3egdLi\xafDl\xb0qjRikh/\x82/Ho\xb3/\x859Jq\xb6mol;\x86:Ut\xb4Xv\xb6?\x8a>|u]tvsB\x8c@@\x8dG\\z\xbby{x]~\xb7e|\xb8\x84|dK\x90J_\x80\xba}\u007f|O\x93Nb\x83\xbd\x8b\x81cN\x95Ud\x85\xbf\x81\x83\x80W\x95Vl\x87\xbc\x8f\x86hZ\x98Yo\x89\xbe\\\x9a[\x87\x89\x86\x93\x89k^\x9d]\\\x9dds\x8dË\x8d\x8a\x96\x8doz\x8e\xbfe\x9ef\x8d\x8f\x8c|\x90\xc1\x9b\x91s\x90\x92\x8fi\xa2i~\x93\xc4x\x95Ā\x94œ\x94\x91{\x98\xc7s\xa4l\xa0\x96xq\xa5s\x97\x99\x96\x83\x9bţ\x99{\x99\x9b\x98u\xaaw\xa7\x9d~\x87\x9fɜ\x9e\x9b\u007f\xabz\x89\xa1˫\xa0\x82\x9f\xa1\x9e\x8f\xa2ǡ\xa3\xa0\xa2\xa4\xa1\x92\xa5ʂ\xb1\x85\xa5\xa7\xa4\x94\xa8ͳ\xa7\x82\x8b\xb3\x89\xa7\xa9\xa6\x96\xaa϶\xa9\x84\x8e\xb6\x8c\x9d\xac̪\xac\xa9\x8d\xb8\x93\xba\xad\x88\x9f\xafέ\xaf\xac\xa1\xb1ѯ\xb1\xae\x97\xbb\x97\xc0\xb3\x8e\xa5\xb4Ԛ\xbe\x9a\xb3\xb5\xb2\xab\xb7ѵ\xb7\xb4\xa3\xbf\x9d\xa2\xc0\xa4Ÿ\x93\xb7\xb9\xb6\xae\xbaԹ\xbb\xb8\xb0\xbc֦Ũ\xbb\xbd\xba\xb2\xbdض\xbeӽ\xbf\xbc\xa8ǫ\xafƫ\xcd\xc0\x9a\xb9\xc0տ\xc1\xbe\xba\xc2ײɮ\xc2\xc4\xc1\xbc\xc4ٲ̷\xd2Š\xc4\xc6\xc3\xd5ƚ\xc0\xc8ݻ\xca\xde\xc7\xc9ƻκ\xd8ɝ\xc0\xcc\xda\xc7\xcb\xdb\xca\xccɿҾ\xc9\xcd\xdd\xd7ϡ\xcd\xcf\xcc\xc4\xd0\xde\xdfϣ\xc8\xd3\xc1\xcc\xd0\xe0\xcf\xd1\xce\xe1Ҧ\xc9\xd7\xcb\xd2\xd4\xd1\xd2\xd3\xdd\xdf֨\xcd\xd6\xde\xcc\xda\xce\xe6֪\xd6\xd8\xd5\xd0\xd9\xe1\xd8\xd9\xe3\xd5\xdc\xd1\xd3\xdc\xe4\xda\xdc\xd9\xe6ݯ\xecܰ\xd5\xdf\xda\xdc\xdc\xe7\xdc\xde\xdb\xda\xdf\xe2\xd7\xe1\xdc\xe0\xde\xe2\xde\xe0\xdd\xf0\xe0\xb3\xdf\xe1\xde\xdd\xe3\xe5\xe1\xe3\xdf\xe3\xe5\xe2\xe1\xe6\xe9\xe8\xe5\xea\xe5\xe7\xe4\xe4\xe9\xeb\xe7\xe9\xe6\xf1\xf3\xf0\xfa\xfc\xf9\xfe\xff\xfcd\x82\x05\xe8\x00\x00 \x00IDATx^\xed\x9d\x0fT\x14\xd7\xdd\xf7\x1fZ\xf3\xc6\xe6M\xda\xd7Q\xf6\xe9S\xe2K\xa9%F\xdbd\x95x\xdeJ\xa0fN\\@\x13\x90*\x82Ę*M\xa2\xb4Q⟜h0\xc4\x1c\xff\xb4.\xc1@\f\th\"I\xa4\xc1\x83A\xa4V\xadx\fA\x03\x96'\xc1D\x92\x87\xa4\xa6nj$QL#\t\x1c\x16\x02\xb7\xf5\xbc\xf7ޙ\x9d\xb93;\xb3\xb3\xc0\xee\x0e\f\xbf\xcf\xd1ݻw\u007f\xf7\xcfܹ\u07fd\u007ff\x98\xdf\u007f\\\x1b<\b\x00\x80\xe1\xc6\u007f\x18\xe9\xd6\aFy\x03\x00\x10r@\xd2\x00`)@\xd2\x00`)@\xd2\x00`)@\xd2\x00\x10`\xfa\x8c\f\x82\nH\x1a\x00\x02\x89+c\x127\xc7\xc8(\x98X^\xd2e3یL̤}f\x99\x91\xc9Hd\x14\xb7\xfaԩ\xce\xcaO\x8c\x8c\x82\x89\x89\x92n\xdeWTrB\f79\xcb}\xda~\xb3y^bN\xbfO\x13m\x9e\xe4\xd6\x19\x99\x04\x8as9I\xa9\xb9\xa7R\xbfR\xc7\u007f\xee\xe0\xefӲ\x17xr\xc2\x06\xaf\xb8\"\x0e\x135\xfb\xa4\x869Ck87\xd5_[?!\x99\xadC\xeb\xf0k\x81\x0f+\xa1`_\x04\xbeիxLr\xce\xfbFv~\xa2\xd5ꁡ\x81\xdbgd\x12dL\x93\xb4\xbb\xd2y\xb4\xf5\xa4\xb3\x85~h/8\\\xec\xd3\xfa\x91Ԋ\xbc\xa4\x0e\x9f&\x9al\x9dPdd\x12(\xea\x93~Sqp)\xcf\u007f\xa4\xfe\xa2\xff\x9d\xcd\x0e\xad\x04\"\xe5\xe1[\xd5QW\x8b\xb8\r\xd5E3\xb9j-{\x99\xa3\x196\xbfm}S-\xfe\"\x90\xcc\xdaPۓ\\\xd1U_\xe6\xb4`\x1f\x04\xa1ջ\xab\xf8\x97NUe\xddu\xca\xc8\xd0\x17\xa7\xceJA\x8dV\x0f\f\xb5\\\x8d\x91I\x901Mҕ\x05.\x84ڜ\xcd\xf4Cy\xa5˧\xa4;\xf8\n\xd4\xdf\xed\xcbB\x9bV\xdbr\xdf\x06mq\x81\x9a v$\xaf\xe9\xc5=/\xd3[\xd2\b\x95\xfa\x924Zis\xa9\xa3\x9a\xe8O\xfd\xcc)\x1a\xd6,\xebl\xfe\xdb\xfadF\x8a\x18\x102\xab\xe6\x9a|Y\x8b\x05\xeb\x12\x94V?\xc7\xd7\xe3_\xc7\xecL#;_d\xad\x97\xc3\x1a\xad\x1e\x10j\xb9\xa3F&A\xc6,I\xbb\x9c\r\xe4M\x18\f\x9a\x8aܾ%}\x81?\xee\xebk]2&u\xfa6h2\xea\xbc~S\x98t\x99\xbc\xed\xe5?\xf5\xfeη\xa4;'e\xa8\xa3\x04em\xe5\fj\xcfH\xda\xd0\xd6'\xd3\x03*頴:\x954\xaa\xe0\a\xf1\xc3.\xb1\x94\x91\xb4F\xab\a\x84\xd1+\xe9\xa3\x05=R\xf8jA\v\xf2!\xe9\xdey<%\x1f\xa1m<\u007fP\\\x9bn\xe3\x1d\x15\xf9\x99I9_P\x9b\v\xeb\xe79RŰ\x8c{\xa24\\\xb4\xa4D\x85O\x9a\xad\xfca\xde:\xa5\xbc\x99k.\x9f\xe2\xc4\xe1ƜtǼ\x9ct\xb2\\\xef\xaf\xcaJ\xca\xcc\xc7]\xe7C\a\xcf0\x97\x9e\x98\xf3\xedA\\~)*\xe5I\xf9\x9a\x06(s\vͳc/\x1e\xab\xfb+\xb2\x92\x96VХ\xff\x17\xb9i\xc9녉\xb7\x94\f\xa9\xea\xbb2\u008d\x94\bʚ\x1fM?\x14ό\x98\xb2\x8c\x88\xe4j\xca$[\xf4\x1c\xfaS\x88\\\xf3'E\xa6dȒVۢ\xce\xe5S'\xc6\x1d\x8dއ\x96p\x13\x8a\xf1\xc0).\u007fe\x83\x9aY\xd1\xe1Q\xb3q\xb2rN`:RIڠ`٠!\x9c\xe3V\xb6̟\x1c1\x9b\x9cTO\xab+c%\xe4Vg\x9a\x8f\x9c\xcd-i\xc9k.P\x13\xad\xb3)H:7\x8d\x84\x99\x96\xec.\xbc/)\xfb\x9d\xb4z\xb6k(\f\xa4\x13{\\\xe8E|\x96\x98\xa1w\xabk\x1e\x90\xf2(\x9c\xd3#\xa6\x93\xee\xa2sl\x88\xb4\xddh\x95tYy\xf3ng\xf1aڪ\xe5\x95ȗ\xa4\xd1G\x8d\a\xf9\xd2\xc6F<\n~\xd1\xe8(\x15צ\xe7\x0e:\xf8\xd4\xd2W\x92\xe9\x0f賓\xacW\xeaK\xf9\xbd\xaa\x84'\xa5\x15f\xf5\xc4\xe9OV\xae\xe36)\xbev\xcd\xe7\xa6r\xb7s)X\xe8\xefߕw\xa4\xbeb\x1e\xff-\x8e\xde\xc2\xe7\xd7W\xa4.\xedG\xbd\a\x0f\xa6gޓ\x96\x9f{\xd7\xe7ݍ\xc9/|\x85\xbez!\xb9\xb1[۠\x97-<ϱ\xb3~\xa7#\x0f\x87.$gV\x1d\xcfᩤ\xa5d\xea\xfa\x1e\xf6\xea\x05M\\\xb9\xbby9G\xb7p2&,)\xdf\x1a5\xbd\x8fh/\xa3\xbad΄Z\x1c\xd92qJQ\xd9,Φk\xdb>9\xea\xc9\xf2%\x1c\xe7D\xae\x9a\xf0u\xd2\xf2W6\xa8\xe5\xe6\xef\xaetFq=\xa8\xf3p͔\xb8\x9a\x9a\x9af13\xb7{\x1f\x95\xb4Q\xc1\xb2\x81\xbb\xa48z\xca\xc4\xe8e\xf39\xb2\xd5\xebiue\xac\x84\xdc\xeaL\U000d1cd9^Z\x9a\x9et\x0e\xe9\x9cM,\xe9\xeeO\v\xf1\xef*b[\xb2#=yo=Vs\x05\xdb5X\x03\xf9\xc4v76ff766zfQޭ\xaey@\x8a\xa3Ȱ\xad,_i\x9b\xaf{l=m\xd53\"\x872]\n\x04fI\xba\xc4Y\xdc\xe0j..\xc1\x9an.\xea\xf4-iv\xe2\xed \xe7T\x98\xc8:\x92\xf1\xefx^*\x0e\xf5\xa6\xe7\u0c71\xf7\xa0z\xff\xac\x9ck\x15\x02\xee\xe8\xd9nr\x1e\xdaU\x06\xfb¹p\xbaAY\x91J\xc4\\\x91\x8c;\xc1q\xbe\n\aϒ\xe1\x18O\xd5\xf8G\xba\x85U\xfc\x96\\\xfc\x92K\x86bM\x83\xcf\xf9\xbfH\xb9\xd6\xd3\x01\x85\xbefg\xe2\xb4\xfdK\x1d\xcad\xaa\xfa\xba\xb8\xddHI\x13\x1d6\xe7\x93`9G\xb6\x9aj\xb9\x17I\xfdIo\xb9\x9d\\\xf4\x9c9\x19\a\xfb\xa6\xdbtm\xe7G\x92\x19\xc92\x8e\f)6\xb2\xfdL\xe7ʌ\x813\x8a\x8c/[#iy\xcc\xc4[\xa0ɏ\x82\x19\x03\x9c\x037몸\x8e\x92Z]\x11\xcb \xb5:۾\x8e\xf4n\xa2\xd0,\xbd\xb3y\x8e\x0e\xb1y\xe4\a\x91i\xc9<\xd2\aP>\x964\xdb5\x18\x03\xe6\xc4*'\xde\x1a\xad\xaew@Rp\x1f\x9d\xc3\b\xaf\x9a\xc76\a7\x9d\xefK7!\xc0,I\x97\x17\x90\xc6\xe8,\xaaE\x9d\x05\xcd}}}\x9f\x14\xfb\xba\xe5F[\xd2y\x9e`\xbd֞\x14\xa6\xccӹʹ\x06\x8d\xafۗ٢\xb9I\xb6eX\xe8\x97\xd3\xd2\xf3+>\xea\xc7]\t\xe5\xa6\xf7~\x8bI\xa3\x13饎\xcfE\xe3S\x89ݨ;锞A\xafC\x1eT\xb6\b\u05ec\xee\xdbL\xb7\xf50;\x1d\xcad\xaa\xfa\xba\x84N\xc4\xd0\xc4m:Z>3\x82\xd4>e\xb2\xbb\a\x13MV~m\xceٓ'r\xb7\xe3\x9aS\xa9\xa2\x956]\xdb\bz\x15\xa9Y%i\xc6\xc05i\xf2\x12g\x03\x12&\x9f\x8c\xa47\xd5\xd6\xd6n\"\x926,\x985@\xd3m\xd2pU\xc6HZ\x8e\x95`Z\x9dm_G!y\xad\xe0;t\xce\xe69\xfe\x95\xb3dz\x12\x89\xb9ܒ\xfdI\xa5\xc2wJI3M͜X/I\xab[]\uf024`\xc6\xed\xf4m\xaa\xda@\xe2\x93}Ω\xa3v\x94\xae\x16~\"\xab\xcbP\xabӃ\xfe\x16\xa4\xb6\xa4\xa5\xe0^\xbeW3\xd9Q\xcf\xdcj+\xe7\xbdnB\xe8\xc9('^\xd5m\x8d\"s֎\x8a\xf5\x99\xfc\xbc\x97\xfa\xc9\xc0!\xb0\x86\x98,\xf5\xac\xbcз\xc9GБy\xe4\xc7^\xdb@\\K\xf7\xe2\xa1\xf9a\xfa\r\xca\xc9\xc2\x03E#\t\xd1J2\xc9T\xf5\xad\xe5\x0e#%tI\xdb>\x81\xc8g\xba8n\xe2!\xb2vR\xf4\xf2\xdd5q\xb8_\x9d\x10\xae\x94\xc8\xdbcj[q\b\xba\xaa\x924\x93\x19jw\xa6L增\xa4\xe5im\x8f\x19\x16\xccf\x86\xa6ϐ*\u007fT\x9e\xd12\xb1\x12l\xab3\xedK\xcf&j\xe4\xcf\xea\x9cM\xba\x96\x16~\"\xe5\x96\xfc\x82?B\xbe\xebVI\x9a=C\xf2\x89UIڻ\xd5\xf5\x0eH\nΜM\xdff\xcfP\x19\xb0\xd4p\xb5\x9a\xf1\xa1\xc3,I\x9f,\xa2\xa3r%\x9e\xa6\xb4\x11\x9a\x8a\xda|\\\xd8PIz\xa7Jҧ\xf8\x0f5\x93u\xda\xc4;\x1e*9\xcd[1\xdct\uf568\xfdl!Y\x98\x1dL\xac ?\xf1g)t\xde\xc7t\x82\xfc5h}>\th\x1b\x14&\xd2\xcf\a\xf9\xaf\xd0\x16a\x97-=\x0f}#\x8c\xd2y\x0ee2U}\xd7\xd9\xd4SSAY\x13I\xed\xe7O>I\xc1\xad3u&\xa9j\x8a<X2\xdbc*\xdb>a\x94n\x92%M\aV&\xb3\x13d\x0f\xeb\xea\x8b\x114#*\xe9\x82O\x14\x926,\x981`~\x14\x98VW\xc4\xcaȭζ\xaf\x83\xb6-\xd9\xd1\xd6>\x9b\xc2\xf6X29\xe7rK\x8a\xa3\xf4G\xb2\xa4w\xaa\x9a\x9a9\xb1biU\xe2\xbc\xc0\xbb\xd5\xf5\x0eH\nfL\xa6o\x933T\x06,\xa3wǻ\x9d^ĺZ\xe0\xb9}\xccߵt\x12\x9e\x9f\xf5\xffF%\xe9\xee\xd4l\xf2Þ\x9f\xafN\x972E\x98\xcewN\x8a#]h\xc92\xb5\x81+R\x98\x1a\x94\xd2\x0e\x83\xb27\x93Y1]$\x17\xbeD^\x19I\xbf\x9bx9\xf1]\x12\xd06\xe8H^O\xf6\xba\xb3\xd3=\x06\aI\x96Y\xe9\xb8[}\x9a\xe8P&Sַo\xeal\xa4BP֤e\r\xeb\xf0ʭ\x84ĬăZ4\xe9D}\xd3\xc9\xecoF4\x9e\xb7\xb6\xd8l\xba\xb6)Q\xa4cΧ\n\x8c\xc0\xea\xed\x9bAl\x19\x83u\u008a0n\t}\x8dÿ\xac\xe4;F҆\x053\x06\xca\x0e\xeeiu\xddn\xefiu\x85\xa4\xe7\xe1\xb5twz\xb6\xbauZ7\b\xd3xAҩ\xf9\xe7Jٖ\\?\x0f\xb7o\u007f\x1e\x95\xb4\xdc5\x18\x03\xe6\xc4\xe2W\x9c\xfbW\xc2wZ\xad\xaew@R\xb0\x9c\xce\xd5_\x14\x96\xcb i5'\nN\xb8\x9a\x8aw\xf7\xd0\x0f}\xae\xa6\"\x97z\xefJB\xd8\xf1~\x87Ν\x1eN}\xa94\x8bwT\x9d\xbb\xdc\xe8\xd8\xfcN\xff\xfb\x9b\x1dd'\xfcT\xe2}\x15\xf5\xc2&\x89\x82\x96\t\xe2\x1ew\xb5m\xaa\xb3|\x89\xfem\x8e\xa5|R\xe9\xf1#[x\xb2V.\xbc+\xf7\xc8_\xb6\xe03\xff\xed\xbbt\x8fT\xfcU\xefO\xcbI\xa3U\xd01\xa8Oz\xb8\xeax\x8e\x83̴s\xf9\xc2\xe3\x85<\xd9O;\x97\x94V\xba3\x99ԗI\xa6\xaa\xef&\xef)\x84pWa\xdcl\xb2x[Υ\x94\x94ep\xc5D\x85)\xce\r\xd3\xf1d\xf9(j\x8a\x88^\xb72rBxQ\xb3\x8e\xadkR\xb4s\xf7\x1c\x1b\x95\xf4̨\r\x1bfr\xc4V\x91\xd9\xc4u\xe5\xbb3\x84\xdd\xe9u\xb6Me\xb3\"\\ʻnj\n\x96\rz\x8e\xd2=s\xcf\x12ZluU\xac7\x8a\xe6s\xf0Y\a+2\x93\xc9~\xb4\xa2u\xe6p\x82\xf4\x04Ig\xe7l^ʶ\xe4\xe5\xd4\xf4\x8a#k\x12\xa9\xad\xd45X\x03\xf6\xc4\xe2\xdf\xff\xbdG\x1e\x11\xee\x1f\xd0ju\xcd\x03R\x1c\xc5\xfc\t\xcb˗O\x98\xef\xeb\xd8Nx\xcd\xe7C\x8di\x92F-eE\xbbO\b\x8aF.\xb2\x94\xd6\x1b\xa7{\x93\xe9\xc2\xc8A\xaf>\\\xc8N\xbc'g'\xcfo\xdbF\xa2>J¯\xdbp\xf4\xa7\xeb\xd3\xee\xc9:\xe2\x9dv\xa5Ml\xe0\x96\x94\xe8\x893\xd4[\x9c2U٥\xe9\x8e\xd4l\xe1v\xc3\xfa\xecy\xc9ٸ\x03}(\xac\xc8rD\x9b\xbd\xd2\x0e\x98\xb6\xc1\xb9\x9c\xa4yk\xe8\xceN\u007f\xc5R\xcfu\xe9\vk\x92\xd3\v\xab\x1c\xb4\x92\x9edHQߚ\b\xaf\xb9C\t^\xd0\xe1EnÔ(2\x1e싋\x8a\x9cId۷i\x8a-*\xa5h\x8a-\x0e\x1fϜ\xc8\xc9ˊ¹%:\xb6\xa8-#:b\xd6\t*閸\x88\x89\xb3\x96s\xdc\x12֠8n]t\xf8\xa48\xf1zӒȈ\xb8Z\xf6\x1eo\xa7a\xc1\x8cA\xc3\x04\xba\x06\x95\x86=\xa1\xd5ձ^(\x9aϑ\xbf%9-O\x90\x1b{6\x8b\xa2\xe8T\x9f\xdc\x18\xf0\nn\xe3\xccyd\xbe&\xb7dǖ\xf4\xc4G\xceRIK]\x835P\x9c\xd8\xde\xfc\xe4\xc4l\xe1\xa6P\x8dVG\x9a\a\xa4<\x8a\xad\xb7Gܾ\xd5+\x96\xa5-<\xa5\xa1\xcdԿ\xae4Oҡa\x99\xad\xc4\xc8\xc4\\^\xb4e\xf4\x18\xd9\f\x9aNa\xe9\x1br\x06\xd1\xea\xc2\xf6\xd8\xe0\xe8\xf6\x9e\x9f\x19\x10\xc4V/\x9b\xca\xc1\x1fW\x06\x95M\xd1\x03\xbf\x9f8\x84\xb4O\n֟\x04\x11̒\xf4 Z=\xa4\x92\x0en\xab\xb75\x04\xe7\xf6q?\xb1\xbc\xa4G5\xa6Iz\xe0\x84TҖ\x06$maZ\xf6q\xcb\xcc\xde\u007f\xf5\x8f/\xe8f\xa7\x91\x95\x0e\x17\xea\xf9\xfcw\a\x9b\xd8z\x80\xa4-\xccL\x8e\xe3\xc2[\x8c\xac\x86\x03t\xb3\xf3s48\xb2I\xe2\vFV\xa3\x06\x904\x00X\n\x904\x00X\n\x904\x00X\n\x904\x00X\n\x904\x00X\n\x904\x00X\n\x904\x00X\n\x904\x00X\n\x90\xb4i\x1c\xcf\xfa*\xb8\xae\\\x80Q\x89\x89\x92\xf68\xd0q\x17\xd1\xc7\x14\x15i=K\xc8¼ė\x92\x9b\x18\x83\xe7\xca\x05\x18\x9d\x98&iفN\xbb\xb3\xc1\x85\x19\xe8\x9f\xee\x8c<\x18\xff-\xe4\x91<UB h\xae\\\x80щi\x92\x96\x1d\xe8\xb4;\xbd\x1f\xb5hIX\xff-\x17\x84'b\x12\x82\xe5\xca\x05\x18\x9d\x98%iƁΨ\x914\xfb\x80\xca-\xa9\x92'\x98`\xb9r\x01F'fI\x9aq\xa0c\xa2\xa45<\xb5\xb0Nq4=\xb5\xf8a\xab\xe5\x8dG鿥\xf7\x1ei\x90\xd6v\xe5\x02\x00\x83\xc4,I3\x0etڝ\x958XcB\xb7\xd6\xf2\xd4\xc2xu\xd1\xf6\xd4bl\xab\xe9\x8dG\xe9\xbf\xe5}\xe1\x01\xdf\x02\x1a\xae\\\x00`\xb0\x98%iƁ\xceU\x1a,y1\xe4\x9a\xd6\xf3\xbb#yu\xd1\xf1\xd4bd\xab\xeb\x8dG\x9ex׳\x0e.\xbd]\xb9\x00\xc0\xa01KҲ\x03\x1d\x84\x9a\x88\x98\xddE!\x1f\xaa\xf4\xfc\xeeH^]t<\xb5\x18\xd8\xea{\xe3\x91%}\x84g\xfe\xde\xdfە\v\x00\f\x1a\xb3$-;\xd0\xf1P\x13\xf2\xa1J\xcf\xef\x8e\xe4\xd5E\xc7S\x8b\x81\xad\xbe7\x1eY\xd2\xef\xf0\xef\xc8yx\xbbr\x01\x80Ac\x96\xa4\x19\a:\x95\x82\xaf\xbf\xear\x9f\t\x82\x80\x9e\xdf\x1dIz:\x9eZ\fl}{\xe3\x11\xfc\xb7t\xb3O\xcf\xf3v\xe5\x02\x00\x83\xc6,I3\x0et\xca\xe9\xf0\xdc^\xd4`\x90$\xe0h{jad\xaa\xe3\xa9\xc5\xc8V\xcf\x1b\x0f\xeb\xbfe}\xa6\xf4\xfc;\rW.\x000h̒4\xe3@\xc7\xe5\xdc\xd7\xf2ɉ\x82\x90\x0f\xd2ڞZ\x14^]\xb4=\xb5\x18\xd9jz\xe3AJ\xff-\x9f\x12\xdf\x11\x02Z\xae\\\x00`\xb0\x98&iƁN[eqQy\x93\x91}0\xd0\xf0Ԣt\x8a\xa3\xe9\xa9\xc5\xc8V\xd3\x1b\x0fR\xf8oA\xe8\x85D\xf12\x96\xb6+\x17\x00\x18$\xe6Iz$\x12\xc0g\xc0\xf7\xe7;\xe8\xd0\x1dDW.\xc0\xa8\x04$=\x10\x02(iԿ7\xad#خ\\\x80Q\bHz \x04R\xd2\x00\x10\x14@\xd2\x03\x00<\xb5\x00\xc3\x1f\x90\xf4\x00\x00O-\xc0\xf0\a$\r\x00\x96\x02$\r\x00\x96\x02$\r\x00\x96\x02$\r\x00\x96\x02$\r\x00\x96\x02$\r\x00\x96\x02$\rX\x95>#\x03k\x02\x92\x06,\x89+c\x127\xc7\xc8Ȓ\x80\xa4G\x1f\xd4s\xcf\xd0\x19\u07be\u007f\xa6NuV\x9a\xf6\xe4YS1Q\xd2\x1e\a:\xca`h\xa9\x8c\x92\xfeL\xbb}IT\xc4lS\xe6j\x9f;\xf8\xfb\x8cl\x10y\xae\x12\xe6\xae\xcc\n\xbf\xefH\xd5\xc9W\xf4\xdc\xd3>+\xf2I\x8do\a@\x80}\xff\x94G\xfa\xff'\xf3\x9e\xf3\x96\xc1q\\D\x8b\x86A\x03\xb7O#vT`\x9a\xa4e\a:l0ԔGHO<\x9b5ə\x11\xd1\xee\xcb8X\xf4\xbf\xb3\xd9ad\x83\xe9x\x89\xafj\xac\xcf\xe5_02\xf4\xa0\x9d\xaf\xc7sϲ\xc9ON\x18\xa2Ӣ\xc0\xfa\xfeY\xce-72\x91\xf0\x9c7WM\xcdV\xcdG&\xd7r5\x1a\xb1\xa3\x02\xd3$-;\xd0a\x83\xe6\xd1\xce\xe1\xee\xd9id\x15$J\xfd\x914\xaa\xe7\xcfa\x9dnc\x9f\x17l\x80F\xbe\x92\xe7\x9e\x19\x1bP\xc4P\xbb}@}\xff\xac\xe4V\x1a\x99hQ\xab#\xe9\x90?pv\xb8`\x96\xa4\x19\a:L\xd0DZ8\xff\xa7}\x01g\x00\x92F\xbd\xc9ی\f%4\xf2\x95<\xf7\xdc^\xe4\xe2\x86:1\n\xa8\xef\x9fu\xdc:#\x13-@\xd2*̒4\xe3@\x87\t\x86\x96\xf6\b\x8e\x9bPLB\xee(\x8e\xe2\xf5Ƞ\xe2\x99\x11S\x96ᱻ!\x9c\xe3V\xb6̟\x1c1\xbb\x87\t\xaa\x8c\xc5\xc7\x17\xb9&\n\x99q\x13UC\x98\x86\xbb\x1e\x84\xbe\xc8MK^/L\x90\x19\x17<\x9a\xb6\x82\xa4Ѷy\xba\xb6\xfd\x15YIK\x85ŶN\xbe\xb2\xe7\x9e\xd9+\xe7\u070e\x8f%\xbcY\xbb4\xff\x1c\tɾ\u007făW %c2S\xe4\xab\xe0I\x8e\xae\xed\xb5\x9bo\t\x17\xee\\6%b\x16\x89\x93\xcf\x1bA[\xbc\xd5 \xe9\xc1`\x94\xb7/\x18\a:L0Ĝ\xa8\xa9\xb1\t#CC͋ܺ\x9a\x1a\xf542c\u0092\xf2\xadQ\xd3\xfb\x90\xbb\xa48z\xca\xc4\xe8e\xf3\xb9O\x98\xa0\xcaZ|Ƞ\xbbh\xab\x80\xcac\xb6\x96\xbb\x1et!9\xb3\xeax\x0eO\xa5'\xbb\xe0Ѷ\x15%]\xc1w\xeb\xd9\xe69v\xd6\xeft\xe4\xe9\xe7\xcbx\xeeY7\xd1v\xa2gv\xdcQ\x9d\xd2\xfcs$$\xfb\xfe\x11\x0f^\x81\x94\x8c\xc9L\x91\xaf\x82\xad\x1c]\x99k7_sq8\x17\xb5n\xd3Dz]J>oHS\xd2=m\xd53\"\xcdZD\x99\x8eY\x92f\x1c\xe80\xc1\xd0\x13\xe1\xe9\x1aZ\x13\xefr\xae\b\x91>C\x9daL\xe7f]\x15\x97\aL\x90\xc5\xf3(\xe0\xb6V\x01\xe5擶\xbb\x9e\xecL\xac\xcf\xfe\xa5Dz\x8c\xb3\x1dm[Q\xd2\xc4\xf9\x8e\xb6m=}\xda0}\xd5Η\xf5ܳ\x81s\xa2\xab\x11䠇\xe0HH\xf6\xfd#?\aYB\xe9=ȓ\x99\"\xc8\xe2\xe4\x84q^\xbb\xf9\x90-\x12\xff\xe0Ώ\x12?E\xf8\x92\xf4\x1c<ƛ\xb8\x8c2\x19\xb3$\xcd8\xd0a}\xe9\x84\x1c\x9f\x92N\x99\xec\xee\xc1D\xd3\x05\xe3t\x9b4*3A\rZ9\x0f\x8aN\xae鮧C\xd0\xc6N\"=\xc6َ\xb6k\x1fQ\xd2U|\x87\x8e\xed\x16\xe1\x9a\xd5}\x9b\xf5\xf2e<\xf7\x94p\x91\xcbЦI=hH\x8e\x84|\xfa\xfeQz\x0frH\xa32\x13d)\xa2?\xa0z͇l\xe4,\xac\xb3\x89\x9f|J\xfa\x93}Ω0J\x0f\x06\xa3\xbc}\xc18\xd0\xf1\xf6\xa5\x13B|Jz\xbaط\xe8lo\xfa\f9^\x0ejQS.\xa0\xdcO\xd6t\xd7sV\x98\a\xd3m,\xc6َ\xb6k\x1fQ҅\xc9z\xb6\x0fS?=('K/_\xd9sO[IJj[\xebdz\xf4Cp$\xe4\xd3\xf7\x8f\xd2{\x90'3E\x90\xe5p\xa4\xa0M\xed\xe6Ct\xaaퟤ15\x9c)#\xc4p\xc0,I3\x0et\x98`\xe8\xf1)\xe9\xf9\x93OR\xe8\x14pz\x8a\x14\xcf\x04\xfdG\xd3]\xcf7\x826\xf2\x84\xd1Tr\xb6\xa3\xed\xdaG\xdc\xf1N]\xafg\xbbEpi\x9d\x9e\xa7\x97\xaf칧\f\x8f\x81s&O\xa4\xd7\xe1\x87\xe0Hȧ\xef\x1fo\xefA\x02Lp\x00\fLҰ\xe3=(\x8c\xf2\xf6\x05\xe3@\x87\t\x86\x1e\x9f\x92\xdeǕ\x90\xb7\x95\xf4&)cIk,'\x19\xb4\xdd\xf5d\xa5\xe3\x0e\xffi\"\x91\x1e\xe3lG\xdbV\x90t!\x11\xa0\xb6\xad\x10{\x90\xac\xa5\xb5\xf3E\x92\xe7\x9e\xdd\\\vj\xe0RP_t\xeb\x10\x1c\t1\xbe\u007fZ\xd7y]\x11S\x14\f\x92\x0e\x15fI\x9aq\xa0\xc3\x06C\x8a\xfbhM\x8d-\xa3\xa6\xe6\xaag\xc7۫\x17,\xe7RJ\xca2\xb8b\xd4s\xb4fJ\\M\r\xe9\xecLP\x85֦/\x83\x96\xbb\x1et.)\xadtg2\xef\xa8:\xa7p\xb6\xa3e+\xdc=\x96\xc7\xd3qR\xdb6\x97/<^\xc8\xe7\xea\xe7+y\xeei\x8bH\xd9\x1d=ŶdCx\xdb\x10\x1c\t1\xbe\u007f\xe6p3\x91\x1a)\x19\x93\x99\"_\x05\xe5\x13}\xcc\xd3\\5\xe1\x19G\xd1Ɍ\xf0\x1a\x17{\xde\xe8\xddc[kj\xbc\xf66N\x8c^o\xa0\xa6I\x9aq\xa0\xc3\x06CI\xed\x04a\xa9\xecD\xeeH\x1a\b\xf7\xba\x81m_\\T\xe4\xcc}X\xf2\x82)\xe9\xecLP\x85֥Y\x16\rw=\b]X\x93\x9c^X\xe5\xe0\xc9\xfd#\x8c\xb3\x1d\r[z\x8f7\x9f.Ny5m\xfb+\x96z\xaeK\xeb\xe4+y\uea5c\x12\xb5\xa4\xb3rJ\xa4S\xa74\u007f\x1c\t\xb1\xbe\u007f\xb6ڢ\x90\x17\x9edLf\xca|Y\xf6E\xf9\xb8-{\t9=M\x11\xf8u\ts\xde\xe8=\xde\x04\xafiS[xJC\x9b)w웎y\x92\x06\x82B_\xfbU\xdfW\x03=\x9e{\x86\x82\xb0=\xa6\xf4\xfd3'N\xcf\xda\x14ʦr\xf0Ǖ\x03\xc6(o \xf4\xb8&\x8d\x193\xc5\xe5SԂ\xe7\x9e!A%\xad\xf4\xfd\xb3a\xd8]\tnk\b\xe0\r\xe8#\b\x90\xf4\x88\x81\xf7\x83_\xfe\xd7\xff*.\x18\xf3_\xbf\xd4\xfe֨\x04\xbf\xf1v$\xe4\x8aڪi\t\x84\x1c\x90\xf4\x88A[\xa6J~\xf9\xbf\xe7\\\xbb\xf6\u007f\xff\xcf\xff\xd3\xfe֨\x04\u007f\x01GB\xc3\x19\x90\xb4\xa5\xe8\x8cL\xb9v-\xf2\xf6\x96\xe0\xde\\\v\x8e\x84\x863 iKA%=\xf1\xf6\xe6\xe0J\x1a\x18\u0380\xa4-\x85 i[ܬ&\x10\xf5h\x05$m)\x04I\x8f\x8d\xfc\xfe\r\r\xbb\xcb\xdbC\u007f\xa9\x1f0\x1f\x90\xb4\xa5\xa0\x92\x9e\xd4~\xad\xe7;aaa\xb6\xa3\xaeNP\xf5\xa8\x03$m%\xfa\xae\x12I\xcf\xc6\xe7\xe6\xfbs\xdc-c\xc3¾\xef\xec\x1c\x9d\xb7P\x8db@\xd2\x16\xa2u\xe6\xf4뱤\xb7\xe2s3\xab\xf9ڵ\x8ce\x87g\x86ŵ\x83\xa6G\x17 i\xeb\xe0\x9e\xf8\xfd\x19\xd7aI\xd7\xe2s\xb3\xfc_X\xdamxĎ\b\xf2\x05-`\xb8\x01\x92\xb6\x0e\raG\xafE`I#|nN\xe0\xffG\xf1\xff\x14[è}\xbc\xc7(\x05$m\x19\xfa6\x85\xfd\xeb\x1aYK\x13\xfe-\xfe\aI\x8f:L\x94\xb4\xe85\xa7\xa7\xd8)P\x8c\x80\xa1г\xe4\xfb\u05eeMJ\xb9\xd6\xe7\xfe\xf7\xb5\x1e\xfcߍ\xff\x13I\x87\x01\xc3\x17\xa3\x93:\bL\x93\xb4\xe45\xc7\xed<\xe9\u009c\x10\x1e\xd0oe\xaaO\xa2`\xe2\x9eo\xbbvm\xfa\x92\u007f\xff\xeb\xda\xc9\u007f\xfd\xfbZCߵk͂\xa4\xbb\x80እ$-{͡7:\xb9\x8b\xad\xff\x14\x8a\x19\x83yd\x99\xff\xb8\xe7D\xd2Ӳ\xf5I\u05f5M\x1b\xae^۰\x01\x81\xa4\x879V\x92\xb4\xdakNy\xe8\x9fS\x14r\x06\xf5\x14B\xffqϊ\xfe\xb7\x17 \xe9a\x8d\x95$\xad\xf2\x9a\xd3\xec\x1c\xa2\x13\xc5a\x84\xd2Î\xc7\x05O\xb9\xf8H\x9d\xe9\xe4\xa1;\x13\x8aQ\xab\x8d\x9b\xaa\xb0e]İ\xf8\xed\x85\xc6=sʿ\xbc\x98\x03\x92\x1e\xceXI\xd2*\xaf9%\x95>\xadG\x14\n\x0f;\x92\v\x9e\xce\xc3\xf4)\x845\xcd\xf4\xd1x\xeb\xf0\x8fZ\x86Ma\xabp\x11\xc3\xe0\xb7\x17\x1a\xf7\xccIȋ\xe8(\"\xe9gn4\xd4\xf5\xfd\xb7\x1aYx\x13F\xff\xe9\u007f\x190\xbc\xf2\xba\xf5~-3\xdf(2Q\x1d\xaeAe\x8d\xda\xef\x89\x1f|\x87\xbe\x87\xdd\xf8\x18y\xf3\xbfvV\x92\xb4\xd2kN\xab\xd3Zϔ\x91<\xec(]\xf0H\x13o\xf6\x01\xb6\xb27\x1e\xa5\x8b\x18\x11\xff\xbdи\x97\x8f\xa9\xb9\xaabwXJ\x13\xee\x8d\xe3^7\xea[\x17ǾE\xbb\x98\x91\x9d\x02}I\xbf>\xde8\xab\xb0\xb0\xb017\xdd\xf6\x94\x91\x19\xc1+\xaf\xb7\xc6^\x14\xbf\x19\\&\xe2\xe1j~\xa7Qq\xa3\xf6\xbb\xe1\xf9/\xe9\xfb\x97\xcf\xdfHޤ\xda\x19b%I+\xbd\xe6T\x96\xf8\xb6\x1eiH\x1ev\x94.x\xb4%-y\xe3Q\xba\x88\x11\xf1\xdf\vM_\xb3-\xec\xfa\x1bn\xb8\xe1{\xdf\xfb\xdeرc\xaf\xc7\\w]\x98\xad\xa4\xd5\xe7X\xea\u125fuu\xdd\xf1\xdb+aW~{\x87\x91\xa9\x8c~\xb6\xbf\xfa\x95\xeeW\x128\xf5\x95\xbf\xfe\xe1Ƿ^12\xd4*\xe8֧\xa4o\x06\x93\t9\\=4\x8eʨ\xfd¾\x14\x03_\n\x96\xb7\xfa\xf5\x1b\xd3e-I+\xbd\xe6\x14\x99\xf2X\xfe\xe0!y\xd8Q\xba\xe0і\xb4\xe4\x8dG\xf9\xf0y\x91\x01x\xa1q7\xad\x9c3+n\x96\xcc\xec\xd9K\xca\x1b\xda\xc3\xc8P\x16&vK\xa2\xef\xa7n\x1e3\xf6\x17\x1f\xe3\x0f\xcf\xde<\xe6\xa6DŽ\xbeu\xdb\x13X\x1b\x8f\xde\x12vˣX\x1c\xcf\xfeh̸\xfb\xbfԲ|t\xdcw\xc7\xd1\x14\x8f\xe1\xc0\xa3a\xaa\xfc\x1e\xfd\x81\x10\x89\x87\xb5?\x93o\u07bam옛\x9fb\x92ɦ]\x1e\x9d|y\v\x99\xa5zJ\xd4/H\xaeԃd\x16\xfc\xc4\x1dC\xca\x04\x1f\xee\xc7t(\xbd8\xf6c1\x1bO\xdd\xe8\xe5beq4\xe6\xadۮ\xbf\xee6\xb6-\xa4\xe2X\xc9\v!O픕\x16j.\xb5\x05\x8d\xf2:\x89C\xc7,I+\xbc\xe6\xb4;}\xb9\xa9\x18\x81H\xe2\xf5v\xc1S@\xc6d*ޕ6\xa5\xad\xb6\xa4\a\xe2\x85\xc6\xdd\xd6ڬ\xa0\xa5\xd5\xd5\xd9'\x8eҲ\xa4ǿ|\xf1\xbd;p\xa7{\xfe\x86g/\xbe\xf5\v\xa1\xef\x8d{K\x96\xf4\xeb?|\xfd\xe2[d=\xe8e\xf9̍/\xff\xe3\xe5\x1b\x9f\xc5\x11?x\xf5\xe2\xab7\x85)\xf3{\xd6\x13\xd9\xf5\xc6x\xfa\xcd\xcd\x0f\xfe\xfd\xca\xeb?g\x92I\xa6\x8c\x0e^\xff\xcf.\xb9D\xfd\x82\xe4J\xfd\xf4\xbfq\xaa\xb7\xc6\r)\x13r\xb8?#?6O\xfd̫Yh\x96\xca\xe2H\xd4\x0f_\xbe\xf8\x8f\xbb\xef\x96s\x97,\xf0\uf0b0\x92&|\x87N\xb9=\xb5S\xe5B^䶠Q\xde'qȘ%i\x85לVg\xbb\x81\xf9\bC\x92\xa9\xc2\x05O\\\x1cBm4\"b9\x9e'\xcf\xf0K\xd2\x03\xf3B\xd3\xe3V҃\u007f8\xbd$\xfd\x06~\xff\x9f\xb1]]?\xfe\x83\xd4\x13\xbb\xc6\\\x94'\u07b7\x10\x83\xf7\xc6iX\xfe\xf8\x19\xfc\xf2̏\xbb\xba~\xf2,\t\x84)\xf3\xa3\x91ϒrȼ\x1b\xbf_\xf7\x9e*\x99d*V\x85pqL\x97\\\xa2~Ar\xa5\xfe\xecI5\x84L\xc8\xe1\xfe\xe1\x16\xfc\xe1\x96?x\xb2\x91\xeaF\xb3T\x16\xe7\x19\x85\xffq\xa3\x9c\xbbd\xd1u\xe5\xb1\xf1]\x1e\xc6?F\x96\x00\x9eکr!/r[\xd0(\xad\x938D̒\xb4\xc2kN\xb3\xd3J\u007f-\xa4\xf0\xb0#\xb9\xe0AD\xad\x9b\xcafE\x90\x8d\xc0\x99Q\x1b6\xcc\xe4\u008b\x9a\x19[\xd6E\f\xcb\xc0\xbc\xd0h\xe0%iO`\xcc\xc7RO\xa4}\xdcc46L\x9c|zY^\xffw\xfc\xf2\xf7\xeb=\x810e~R$\x99w\x93\x88_\x8d\xbd\xfb\x89\xf7\xd8d\x92)\xf3F\xba\xbfT\xa2~Ar\xa5\xaexR\r!\x13r\xb8Wƾ\xd7\xf5\xde\xd8+\x9el\x94\xed\xa3,\x8eD\xfd\xf7\xcf\xc7*r\x97,\xf0T]\xfem\xfc\x03\x8d\xf1\xd4N\x95\xcb\x15\xb6RB\x94\xd1\xc9\x1b\x04\xa6I\x9a\xf5\x9a\xd3\xea\xf1;n\t\x94\x1ev<.x0\xee%\x91\x11qt?\xb0%.b\xe2\xac\xe5\x1c\xb7\x84\xb1e]\xc4(\x18\x90\x17\x1a\r\xc2\xf4$}=#\xe9q\xcc\x0e\xf0\x18qp\xf5\xb6\xf4S\xd2\u007f\x1e'&\xfe\xf3\x83\xb7]\xff\xa0\x81\xa4ɜY*Q\xbf U\xa54&\xde\x03Ʉ\x1e\xee\xdd\xf7w\xdd\u007f\xb7\x94\x8d\xb2}\x94ő\x97\x9f\xfc\xea\xbd//2m!Yt]\xf9-3J\xff\x96(\xd5S;\xef\\Tma-I\x03!B\xec\xa5c\xff\a\xbf\xbc\xc1\xf6ݟ0\x13o\xb2=\xe6\xe1Ǐ\x8a\x01/K퉷d\xe5\x99x\xd3\xfdnQl\u007f\xbd\x8e\x9dl2يo_\x92\xa5\xa6T\xa2~A\xaaJ\xa9\xb6\xc7\x06\x9a\t=\xdc\xd7\xc7w\x8d\u007f]\xcaF\xaa\xdbwȖ\x97\xb28\xf2r\x1d\x1e\xd8_e\xdb\xc2c\xa1\xb1\x96\xf6\xd4\xce;\x17U[\x80\xa4\x81A v\xd7;\xeex\xef\xe2\xcb\xe3پ\xfb\xea\x8d\xcfK\xdbc\xecU\x9d\x97\xaf\u007f\xe2\xe3\x8b/ߪa\xf9\xccMd\x9fI\xbd=\xe6\xb1zv\x1c\x8e\x1c\x87\x03\xe3\xdf\x10\"n}\xfe\xe2\xc5Gof\x92ɒ\x16\xd2]yO\xb8\xfe$\x95\xa8_\x90\xaaR\xf42\xd1\xe03\x11\x0ew\xfc\x83\x9e\xe1\x95=\x8cq\xcf{\xb5\x01y\xb9\xf9\xc1\x8bo\x8cg\xdaB\xb2\xe8\xf2\xa4\x95C\x9e\x8bX\u07b9\xa8\xda\x02$\r\f\x02\xb1\xbb~\xfc\x8b\xb1c~\xf4\x14\xdbw\xbb\x9e\xf9ј\x1f\x88\x17\xb1\x14\xf7^\xbc\xfa\xd3\xeb\xc6\xfc\xf4e-\xcbG\xc7}G\xbc,\xf4\x03\xf9\"\x96d\xf5\xe8M\xdf\x1d\xf7\xe0\x18a\xdeM\"\x9e\xffɘ\xb1?\xff+\x93L)ir\x97\xc8ϞR\x94\xa8_\x90\xb2R\xc2\xcd\x1c\x83\xcfD8\xdc\xfb\xbf\xeb\xb9͋=\x8cgƑկ\xa28\xf2\xf2\xc6\xcdcn\xfa-\xdb\x16Rq]\xea\xeb\xd2\xf2\xad&^\xb9\xa8\xda\x02$\r\f\x82\xb0.\u007f\x18\xcc\r\xa1Z\xe0\xd9,\x9dw\u007f9\xc6\xc8r(\xf8\u007f˥\x0e\x81:\\\x81\x9b\xa4\xbb\xc7n\"o\xfe\xd7\x0e$\r\f\x02\xff$\x1d\b~\xf1狯\xff\xf0Aa\x81\xfa\xfa\xcdF\xd6\x16≛\xc4{\xbcox\xcc\xc0R\x05H\x1a\x18\x04\xa1\x93\xf4\x13\xff9f\xfc\x83B0l\xfc\xab\xbem\x01\x02H\x1a\x18\x04\xa1\x9340P@\xd2\xc0 \x00I\x0f_@\xd2\xc0 \b\x03\x86/F'o\x10\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x8cfI\xa7pQ\U000db34c\x00`d1\x9a%\xed\xaa.\x9a\x1a\x05\xeee\x00ka\xa2\xa4E\a:\bu\x1e\xde]\xb0\xfb\xb0)ڪ\xe6,\xef\xe3\x03\x18e\x98&iɁ\x0ej/\xde\xdd\xecj\xde]lƓMj\xb9\xa3F&\x000\xa20MҲ\x03\x9d\x9a\x12\xf2 \x84\x9e\x92\x1a\xa3$A\x00$\rX\r\xb3$\xcd8Щ\x14\x9e\x12Zf\xc6\xd3\xf9AҀ\xd50KҌ\x03\x9d\xf6\xe2\xeavw{\x8d)\x13\xef\x06\xae\xda\xc8\x04\x00F\x14fI\x9au\xa0\x83\x97\xd5N\xe7>S\x9e(莚q\xd8\xd5gd\x05\x00#\a\xb3$\xcd8\xd0qW\x964\xbb\x9aK*Mq]\xb9O~\xf0\x1f\x00X\x01\xb3$\xcd8Щ\xa1\x8e\xb1\xdc%f8\x98\ue31a\xbc\xb5\xdab~\x01\x80эY\x92f\x1c\xe8\x14\b\x97\x86\x1b\n|\xd9\a\x89ZΌM9\x00\b\x1efI\x9aq\xa0#J\xfa\xa49\x92\x86\x1do\xc0Z\x98%iƁN\xb58\xf16c\xef\x19$\rX\r\xb3$\xcd8\xd0q\xbfX\xd2\xe4j*yь-\xef\xa3 i\xc0b\x98&iƁ\x8e\xbbvw\xd1\xee\xda\xd0+\xda\xed:\x99b\xb3\x96\xafz\x000O\xd2\xe63\x87\xe3\xa2ˌ\x8c\x00`d1\x9a%\xed:\tC4`9F\xb3\xa4\x01\xc0\x82\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x98(iɁN_CY\xc1\xee\xe1\xe3o\xee\\Nrr\xf6\xa9\xa5\x8dFv\x02\xf5\xa9\xc7\xf5\xbf,\xe5\x1d\xe4\xdb\xfa$\xbeT\xdb`\x1b\xcf\x1f\xd4\xfe\x06}\xee\xe0\xef\xd3\xf9*\xb0\x8c\x88J\x02~c\x9a\xa4e\a:\xa8\xbc\xe8d뉂\x13F)B\xc4Yǚ#\a\xd7\xeb\xf7b\x15Ǔ\x8e\xe8\u007fّ\x9b\xf4\b~{$1\xb7C\xf9ũ\xb3\xc2\xfb\x17\x8d\x0e\x1d\x1d\xa1\xfew6;t\xbe\n,#\xa2\x92\x80ߘ&iفNC\x01y(\u007fK\x81)~\xee\xbc\xc9\xc9\xee\xc7]u\xb3\xbf\x92F\xfd\xbe\xbe,\xccI\xea@\x1d\x899\x85\xaa\xf8\xac\xf5\x9e\x90\xaeZ\xf0\xf0\x19\"\xb5\x8c\x88J\x02\xfeb\x96\xa4\x19\a:\xe5\xfbhL\xf10\x19\xa6\xd3i\xcf>\xc7\xfb\x18|\"\x05\xd7\xcf\x00\x00\r\xafIDAT\xfd\xa70\xf7\x91\x83\xa8*'W\xad\x96\xa5\xc3I-#\xa2\x92\x80\xbf\x98%iƁ\xcen\xc1\xbf]Y\xb9\xaeqp\xf8\xd0\xc1\xf3;/\xe4\xa5'\xe6|\xcbF禞ï\xfd\xf5\xdd\xe4\xb5*+)3\xbf[a{\x90\xe7\U00062cd4'S\xf3\x8e$^\x9e\xa1_X?ϑ\x9a\xf3\x05\x9b\f\xab\xa5b=ʩ\xa0j\x91b\x8f\xf3\x02Y$\x95\xa30?3\x89\xa6B\xfd\x15YIK+\xe8\xa8\xffEnZ\xf2z՜\xd65\x91\x13\x98\xa8zr\x83\\\xb0\x84\xe2\xd8\xe4\xea\xa0\xee\xc2\xfb\x92\xb2\xdfI\xabW\xa4\x0fd%\x01\xd31KҌ\x03\x9d\xc3\xc5\xf4\t\xa1E\xbb\x8d\xd2\x04\x98ރ\a\xd33\xefI\xcbϽ\xebs6\xfa\xf3t>\xa7\xf4\xdd^\x1a\xde\xc2\xe7\xd7W\xa4.\xedgm\xbb\x1b\x93_\xf8\n}\xf5Br#\xee\xf8g\x1b\x1b\x13\xc5\x11\xecTR\xd6+\xf5\xa5\xfc^6\x19V\xcb\x17I\xdf$^\xa6j\x91b\xbb\x1b\x1b3\xb3\x1b\x1b\x1b?%\xc9\x1c|\xe6\xc1\xe3\xf3\xe8x\x98\xe7\xd8Y\xbfӑ\x87C\x17\x923\xab\x8e\xe7\xf0J\xb5\xb8\x8b\xb6\n\x14)\x1f\xd3\xc6\x14,\xa186\xb9:\x1d\xe9\xc9{\xeb\xb7\xf1|\x85\"\x83@V\x120\x1d\xb3$\xcd8\xd0\xe9,*os\xbbʜ%Fi\x02\xcfR\xfe\x91n\xd4߭\x8c\xec(\xfd\x8d\x83O&c\xefq\xbe\n\xbf\x9e\x15\xc6a\xd9vK.~\xc9\xdd\"\x9a\x8b\x92\xeeM\xcf\xe9%R\xeaP$+\xccEK7g!\xa2\x16ef\xf2\x9c6\xf5\x1b\x9cc*\x0e\xd5\xf3\xf5\x9e\xd7\xecL\\N\xffR\x95Z\xdaZ\x05\xda\x14\xb1L\xc1\n\xa4\xfa2\x05\xe7%\x93\x916\xdfK\xd2\x01\xac$`6fI\x9aq\xa0\x83\xda˝N\xe7\xd1r\x13\x9e\xec\xb7ԡ\x18\xa0%zO\xe5\x90N\x9b\x9b\xde\xfb-&m\x8b\xd2\xf6Tb7\xeaN:%~\x12%]\xcf\u007f\xe4I\xcd$\xc3jy\x85\u007f\x89\xaaE\x99\x99\xac\x16\xf2\x99.H\xb7\b\x97\x83\xeeی:\x04\xcd\xedT\xaa\xa5\x95\xf3\xa0\xf0\xf8\xc3\x14\xac@\xaa\xaf\\p\u007f\x12\xad\xeb9oI\a\xac\x92\x80\xe9\x98%iƁ\x0e\xc6\xddއ\x8aM\xf0\x89\xb54\xcb;\ueb30d|x\r\x19\xe8\x04\xd6(m\xbfM>\x82\x8e\xcc\xf3\xect\x8b\x92\xde\xcb\xf7z\xbeg\x92a\xb5t\x14~Eբ\xccL\xb9\xf3D\xd5\xf20\xfd\x06\xe5d\xe1Q\x92^\x14W\xef<Ք\v\xd4(b\x99\x82\x15H\xf5\x95\v\xfeB\xd8\xf3\xeb\xf6\x96t\xe0*\t\x98\x8dY\x92f\x1c\xe8 \xbaQ\xd6\xe24\xe1q\x9dr\xa7\x95Iͧo\x85\x99d\xcc:K\xe9P\xd9\xe6\xafA\xeb\xf3=\x1fDI\x9f\xe2?\xf4\xc40\xc9\ns\x85\x98B\xad̪\xc80*\xabeK:\xf9\x95\xe8O\xcfC\xdf\b\x9a\xcb\xf3K-L\xc1\n\xa4\xfa\xca\x05\x8b\xa3\xf4Gޒ\xa6vA\xac$\x10:̒4\xe3@\xa7ى\x17\x87W\x8b\xcd\xf0\x9f\xc3J\xbau\x830\x9f\x9d\x97F\xfas?\xf9\xaa^XS\x16\xbe\xa4\xb2}7\xf1r⻞\x0f\xa2\xa4\xbbS\xb3\xc9h\x99\x9f\xafHƨE\x91Yv6B_\xd1\bY-\x82\xc1A2\xe3\xcfJ\xc7u\xf84\xd1/\xb50\x05#\xf9(\x98\xfa2\x05\xaf\x9f\x87\xf3\xed\xcf\x13%\xed\xb1\rA%\x81\xd0a\x96\xa4\x19\a:-\xceZWCqyȽm|\xfb.\xdd\xd3\xf5\xac\x90\xe7\x88~\xa6\xe7\xf1\xa9\xa5\xf5G\x1eI\"[\xbd\x85w\xe5\x1e\xf9\xcb\x16܋\x95\xb6\xfdi9it\xde\xdd\xfbNcc\xe2\xe6F\xb2\xf7\x8dW\xd8\xf7U\xd4\v;OR\xb2or\xb3/\xe3ϗ\xb3s\xbfab\x11\x91\xc7^\\\xc4et\xb9ѱ\xf9\x9d\xfe\xf77;\x1a\xb1]._x\xbc\x90'\xfa:\x97\x94V\xba3\x99wT\x9dC\xc60\x05KG\xa1\xa8\xaf\\\xf0\xe5\xd4\xf4\x8a#k\x12\x95\xb6!\xa9$\x102L\x934\xe3@\xe7dIQ\xf9I#\xf3\xc0\xf3\xa1\xb0l\xcc\x11?\x16E9\xe9\xfbo*\n\xefKJ]C/ޠ\xfa\xecy\xc9\xd9\xf5^\xb6{\x1d\xc2%\xa3\xf7ť'\x95ȧ\xeb\xd3\xee\xc9:\xa2HV\xca\xf3dci3Oo\x9f\xf6\xc4bz\xf3\x93\x13\xb3\xcf\xd2ۧy\xc7G\xe4\xea\xf66r\xc9w\xa9\xe7\x92\xef\x855\xc9\xe9\x85U\x0e\x12k\fS\xb0\xe7(\x94\xf5\x95\v\xeeؒ\x9e\xf8\xc8YQҢmh*\t\x84\n\xf3$\r\x98\x85z{\f\xb0\x14 \xe9\xd1\aH\xdaҀ\xa4G\x1f iK\x03\x92\x1eu\\\xa8\xe7\xf3\xdf\xf5\xf9\xf7c\xc0H\x06$=\xea\xc8&\xbb]\x17\x8c\xac\x80\x91\nH\x1a\x00,\x05H\x1a\x00,\x05H\x1a\x00,\x05H\x1a\x00,\x05H\x1a\x00,\x05H\x1a\x00,\x05H\x1a\x00,\x05H\x1a\x00,\x05H\x1a\x00,\x85I\x92\xee)v\n\x14\x93O\xae\xb2\xa2}&<\xd3\x04\x00,\x88I\x92v;O\xba0'\xe8\xb3M\\\x055-5\x05\xa0i\x00\b\x00&I\x1a5\xd1gw\xd3G\b\xf6\xd1\xd7\xc3\xc5}\x06I\x00\x000\xc6,IS\xca\xc9s\x8aPs\x01\x95w\xc1\xf0\xf1]\t\x00#\x173%M\x9f#\x88P\xa5\xe0\x13\xab܌\xe7\t\x02\x80\xd50S\xd2%\x95\xf4m\xb7\xf0\x00\xef\xc3&<\x9a\x1f\x00,\x87\x89\x92n\x15\x9f\xdc]\\K\xdfj\x8b}\x19\x03\x00\xe0\x17&J\xbaRt\x82%z\xae\xac\x0e\xb5\x9b;\x00\xb0\"&J\xbaHt(])x\xa1-\x83\xb54\x00\f\x1d\xf3$\xdd\xee\x14\xfdB4;\x89ǻ\xabN\xd8\xf1\x06\x80\xa1c\x9e\xa4[\x9d\xedB\xa0\x8f\xfaΩ\x86\xeb\xd2\x00\x10\x00̓t\xb3\xd3\xe32\xc7UP\xddZ\rw\x8f\x01@ 0Oҭ\xf2v\x98k_A\x19(\x1a\x00\x02\x81y\x92\x06\x00 \b\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\x01\xc0R\x80\xa4\xd1ڵZA\x00\x18\x99\x98$i\xa5\x03\x1d\x84\xaa\xcd{\xa4\xc9\xdf\xecOk\x04=\x1c\xb0c\x12p\xe0\x83_\xc7\xc7.:\xb6\xe0m\x1c\xdc>\xf7\xceiw\xce݁P\x9dݾ\b\xa1\xfd\xd8\xe2\x98:]\x908\x16\xff')|~\x9a\xfd^\x1f\xa6\xbeYk\xb7\xef7\xb2\x19\x10\x81k\xa8\xd5\xd8,漑\x15\xa0\x87I\x92V8\xd0A\xa8\xcdYk\x90 x\xac\x8a\xb9\xa4\x11\xf4\xe0~\xbb.v\xc5\a\b\x9d\x99\xf6Ё\xfd+\xa8\x0e\x8e\xd9\u007f\xbd\xe7\xd0k\x0f\xd9\xeb\x90\xfb\x98=\x06\xbf\xee\xb7\x1fs\xa3\x00s\xec\x8cf\xf4\xa1\x18F\x88\xa7W\xc7h\x1a\xf9å\xbai;\x8cl\x06D\xe0\x1a곺\xba=\xf6\xb7\x8d\xac\x00=L\x924\xeb@\a!W\x89y\x92>oߨ\x11d\x89'C\xf7\xe2\xc5$\xb8\x9a\xf4ԍ\xb1\xb4\xee\xb1\xd8\xd8m_\xb5\x9a\xa4\xf3\xa3\xa3\x0e\x90\x05+\x8c,0;\x06/i\x84b\x02+i\x14Ȇ:\r\x92\x1e<fI\x9a\"8\xd0A\xd5\xce\xea\x02\xd3$\xbdZ\x1e\x99W{\x0f\xd2\x04\xdaS\x13\xb6\x93\xe0\a\xf6\x03\xb8\xd3.\xa4\xd1\v\x17\x93\x9ez\fw[\xbf{\xea\x00\x18\xb1\x92\x0eHC\x81\xa4\x87\x80\x99\x92\x16\x1d\xe8 \xb7\xdb\xf3x\xfe\xd0s~\xdaF\x8d\xa0\x02\xdaSW\xc4\u007f@\u0087p\x9f\\$\xa8m\xc5\"\xd2S\xcf/د\xee\xa9g\xa6\xd9\xed\xdbϯJ\x88y\x80< q\xff\xa2\x98\xb9\x1b\xe9\xf7\xee\xa7\xef\x8d]\xf4v\xc2!\xf48\x99\x96J+a٠nq´\xf8_\xe3\xf5\xe8\x9f\xec\x02\v\x90\x82\xafc\xec\xd2\n\xf8Ҫ\xf8\xd8\x15\xde\x13\xef\xf3+\xe2q\x16\xf8\x97\xa9\x13\a\x12\x1e\"\xb3\xf7\xc7\xed\xd3\xf6l\x9c\x1b\xb3\xf83\x95i\xccƵ\xf1w>$\xacY\xe5:\xc8h\xe6p\b\xd7\xe0\xf7h\x87]s%>І\"k\xeb\x1dbfri\x04Q\xd2z\r\x85\xd0k\xf1{\x10\xa0\x8d\x99\x92\x16\x1d\xe8\x10L\x93\xf4\xdai\x9fi\x04\x15О\xfaY\x82\xfd\x81\x1d\xa7\xe9\xa4b\xc1\xefh\xf4\xef\x16О\xba\xeb\xd7\xea\x9e\xea\u07bf?anl\xc2\xc6U\xf6\xcf\xc8\ft\xe3\xa1]\xf1\v\xb0\xb8\xbfN\x88\xdfuh\xadݾG\\NJ+a\xd9\xe0\x8c}\xd5\xfec{\xe2\xed}d]:wQ]]\x9dz\x8f\xe8L]\x9d8\xb6\x9e\x8f\x9d\xfbڟ\x16\xdbՒ~3v\xc1s\xc7v\xd8w\x11\xed\xad}s\xffC\xf6\xd3\b\xfdm\xff4{\xfc\x8e]\xb1\xeaa?ƾ`\xff\xfe\x051D\x80r\x1d\x184sp\xbf\x9d\xb0\xf6\x12\xba\xb4=\xb6Nc\xbc\x1dpC\xd5\xc5n\xf7d&\x97F\x10%\xad\xd3P\x98\x15\xf6\a\x10\xa0\x8d\x89\x92\xf68\xd0!\x98%\xe9Ϧ\xad\xd5\b*\xa1=\x15}\xfd\xdc\xc2i\xf6X26ݻ\x8aF\xaf\xba\x97\xf6\xd4K1\x97\xbc\xe7\x93\v\xec\x8b;\xf18Gt\xf1GDz(N\xb7*\x96L\xeb7\xda\xc9\xf0B\x85I\xa7͌\xc1\x9ex\xd2]\xf7\xc4\n9\xe8L\xbcEI/\x9a\x8b\x8b\xec[\xa0\x92\xb4;\xe1\x01\x1cݳ\xffk\xf2\xbbB\xea$\xe4\x12\x13\x8b\u007f[Vūs\xba\x17[\xb8\xe7.Tԁ\xcdL;\x87\x1dd\xea@\x16\xc6\xde\f\xbc\xa1V\x93\xdc\u007fGڝ-\x8d\x99xk6\x14\xe6\xfcs\xb0%\xae\x87\x89\x92\xf68\xd0!\x98%\xe9ǧ\x9d\xd7\b*\x89\xf7\\\xd9r\x1f{\xc0~H\x1a|V\b\x83\x0f\xfa\xf5.\rILj\x03\xfe\x8a\x84\x9e>L\x02\x96@\f]d\xfeM%i\xc6\xe0\xb3\xf8\x84\xc7\xf7\x9cA=B\x0e>%\xfd5\xcd\x05mWI\xfa\x90]\xde'\xff\xe7\x9e\a\x12b\x85\xa9{\f\x11\xa0\u05fa;\xe6\xf7\xe4u\x8f\xfdk\xb6\x0e,\xda9|f\xff\x00\xb9c5\xafE\r\xbc\xa1ތq#wL\x1d\t2\xa5iJZ\xa7\x92\x80\x17&J\xda\xe3@\x87`\x92\xa4/Ŭ\xd5\b\xaa\xa0=\xf5\xb4\xb0s\xb6\xe8!\xe1?\xe6!a\x89\x88\xf6/А\xb4g\x15\xbc@\\\x15\xaf\xc0R8@\"\xdc*I\xcb\x06X\xa8{V\xdck\x8f\u007fNH\xe8S\xd2g\xecT\x06j\x99\xee\x92+r:>\xe1\xe9\x03u\x8b\x17Hi\xbc%Ms\xaaÿ\x02l\x1dd\xf4rx\xe0it,\xb6\ai0\xf0\x86\xea\x8b?\x80\x0e\xd0\xc9\t[\x9a\xa6\xa4\xb5+\txc\x9e\xa4%\a:\x04\x93$\xbd\xd1~^#(\xd1G\xa3hO\x8d\u007f\x9c\xc6l\x9f\x8b\x90\xd8\xef\x16,\x16z\xaa;昷\xa4=\x1doU\xc2\x19\xca?Q\x9f \xa1\x0fdI\xd31V6@gH9_\xef\x8f\xd9#\xe5\xf0\x9a\xf7\xe2^\xc8\xe5\x9f\xc2(\xad\xde\x1e;&\x8f\xd2\xf7.$uZ\xe1K\xd2\x1b\xc9\xebk\xf6N\xb6\x0e\fz9\xfc)\xbeg\xb5z\xa8\x1ctCm\\\x81Vl$\x01\xb64\xb5\xa4\xd5\r\x05\xf8\xc4<IK\x0et\b\xe6H\xfaR\xccj\x8d\xa0\xcc\x1e2\x18\xfe\x93\xec6\xa1\xf8\x84\xafI\fQ\x9ax\xb9\x95\x8cꤧ\xa2տӗ\xf41a\xed\xb7\xfd9\xb2\x15Lz\xe3*AҸ\xf3\xf7-\x8cQ\x1a\xec\x10n\xadZDg\v\x8b\xf0\xd0vIc[Y\\K/$\xd59\x1f\xa3\x92\xa9;~\x11\x19>7nD(\x81Ԡo\x81/I'\x90u\xf7\xbd\x8b\x14u`\xd0ˡ'\xfeOw\xaa\xe7݃n\xa8\xd31\x97b\xe8\x96\x18[\x1a+i\xad\x86\u009c\xdf\x01ki=̓\xb4\xec@\xc7\xedr\x15U\xbb\xda|Z\a\x85\xa7\xe5\x91\xf9i\x8dA\x9a\xdc\xfe\xb4\xff\x8f\v\xe3\xc9X\x19o\x8f\xdf~\xec\xc0br\xa3\xe21\xfb\x03\a\xea\x0e,\xc6\x13i7\xeegnT\x17\xa3\xec\xa9}\xa7\xe9~\xf5y1\xdf\xdf\xed?@o\xbc\xb8\x14\x9f\xb0\xe7\xc0\x8a\x18*\xe9E\xf1\xcf=\xb7\xd0>\xed\x8f\x1f\xb0\x06;\xec\xb1\xdb\x0f\xe1\xe0\x9b$ݎ\x98]\xb84\xe5(\xdd\xf3v]]\xcc꺺N<\xd8\xc7$\xec\xd8~\xa7\x90\x03ñ\x98{\xf7\x1c\xdah\u007f\x8dd\xb6b\xcfs\v\xf04\xfe\xf4\xa5\xbai\xabO\xa33\xab\xa7\xd5)\xaf\xba\xc7\xd8\x1f8}lQ,\xa9\xa6\\\a\x06\xdd\x1c\x9eN\x88U\xbb/\x1b\\C\x11\xe2\x17\v\xdbvri\xc2\xddc\xbb\xea\xeaHn\x9a\r\x85y\x88\xdc`\nhb\x9e\xa4e\a:'\x84۽\xaf\xfa\xb2\x0e\x06\x97bVi\x04Y\x0e,\x88\x89}\x88\xaaf\xe1k\xdb\uf349\x17.\xe3n\x9f\x1bk\x8f%\xb7.\xbfI/\xa9\xf6-\x8cWt\xf13¢OXH\xa2c\x8b\xe3c\x17\x1d\"\xa1\u007f\xaeN\x88Y|\x86J\xfa\xfc\xa2\x98\xd8ſ\xb7\xdbײ\x06\xfb\x17\xedH\x98\x16\xbf\x88*\x1a\xb97\xde\x19\xb3\xe84R f,\xe4\xf0Н\tO\xffq\x1á\xe1\xfc\x8a\x84\u0605d\xd1\u07b7knL\xfc\x8a\xd7\xe6N[\xb4\x16\xa7\x98\xf6\x01\xb9\xa4\xad\xb4\xbdwNJ\xd8\xf8U\x82\xcc\xe5J\xca\xe8\xe6p^](\x1adC\x11v\xc5\xec\xa2\xefri\xf4\x1eoϪY\xb3\xa1h2\xf5\x06>\xe0\xc1<I\x9b\xcf\xef\xed\u007f\xd3\b\x06\x17a{lD\xe3\x8ey\xd3\xc8$\xf8<\xb4\xd8\xc8b\xd42\x9a%m\xc6_UZ@\xd2\xfb\xbd\xc7ڐ\xf3\x9c]5\xa7\x00$F\xb3\xa4\xcd`\xa4KzǛh\xf1v#\xa3\xa0\xf3Y\xfc.#\x93\xd1\vH:\xa4\x9c?fߨZ!\x8f(\xdc\xf6\x05\x8f\xc7\u007fmd\x05\x98\tH:\xa4,\";M#\xf9\xfa\xcb\xf6\xd8\xc5#\xb9\xfa\xa3\x01\x904\x00X\n\x904\x00X\n\x904\x00X\x8a\xff\x0f\xb8\x98\xba\xeaw\xacpV\x00\x00\x00\x00IEND\xaeB`\x82", "analysis/ipcg-func.png": "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x02\xaa\x00\x00\x01\xb1\b\x03\x00\x00\x00\x9d\xa2d\x9d\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x02\xfdPLTE\x02\x04\x00\a\t\x05\n\f\b\x0e\x10\r\x13\x15\x12!# '(&+-*2319:8?@>QSPVXU,`\xae7]\xadZ\\Z8^\xae8a\xaa:b\xab;b\xac^`]<c\xad=d\xae?e\xaf@f\xb0Ag\xb2Bh\xb3Ci\xb4fgeCk\xafEj\xb5Lj\xafMk\xb0Fm\xb2Ol\xb2Ho\xb4Ip\xb5Jq\xb6molKr\xb7Ms\xb8Nt\xb9Ou\xbaPv\xbbrtqWv\xb6Xw\xb7Yx\xb8[y\xb9wyv\\{\xbbV~\xbd^|\xbdX\x80\xbf`~\xbeZ\x81\xc0`\x81\xbbb\x80\xc0}\u007f|b\x83\xbd\x80\x81\u007fc\x84\xbed\x85\xbfe\x86\xc0\x82\x84\x81f\x87\xc1\x84\x86\x83h\x88\u0085\x87\x84i\x89Æ\x88\x85j\x8a\xc4k\x8bƈ\x89\x86q\x8b\xc1r\x8d\u008a\x8c\x89s\x8e\xc3t\x8f\xc4v\x90ō\x8f\x8cw\x91Ə\x91\x8ex\x92\xc8q\x94\xc9y\x93\xc9z\x94\xcas\x96ˀ\x94Ł\x95\xc6z\x97Ǔ\x95\x92\x82\x96ǃ\x97Ȗ\x98\x95\x84\x99\xca~\x9b\xca\u007f\x9c̆\x9b̀\x9d́\x9eΈ\x9d\u0382\x9fϛ\x9d\x9a\x88\xa0˄\xa1ѝ\x9f\x9c\x8a\xa2̌\xa4\u038d\xa5Ў\xa6ѣ\xa5\xa1\x8f\xa7Ґ\xa8Ӧ\xa8\xa5\x91\xaaԘ\xabє\xac֙\xacҪ\xac\xa9\x9a\xadӛ\xaeԭ\xaf\xac\x9d\xb0֘\xb4ذ\xb2\xae\x9f\xb3ر\xb3\xb0\xa0\xb4٢\xb5۳\xb5\xb2\xb4\xb6\xb3\xa3\xb7ݝ\xb9ݨ\xb8ض\xb8\xb5\xaa\xb9ٷ\xb9\xb6\xa4\xbcڬ\xbb۹\xbb\xb8\xad\xbcܮ\xbdݯ\xbeߩ\xc0߰\xbfཿ\xbc\xab\xc2\xe1\xb1\xc1\xe1\xb6\xc1\xdc\xc0¾\xad\xc4\xe3\xb7\xc2\xdd\xc1\xc3\xc0\xb8\xc3\u07b2\xc5\u07b9\xc4\xdf\xc3\xc5º\xc5\xe0\xb4\xc7\xe1\xbb\xc7\xe2\xb6\xc9\xe3\xc6\xc8ż\xc8\xe3\xb8\xcb\xe5\xbe\xca\xe5\xc9\xcb\xc8\xc0\xcb\xe6\xba\xce\xe7\xc2\xcd\xe8\xbf\xcf\xe2\xcc\xceʼ\xd0\xe9\xc3\xce\xe9\xc7\xcf\xe4\xc8\xd0\xe6\xc3\xd3\xe6\xca\xd2\xe7\xd1\xd3\xd0\xcc\xd4\xe9\xc6\xd6\xea\xd4\xd6\xd2\xce\xd6\xeb\xcf\xd7\xec\xca\xd9\xed\xd0\xd8\xed\xcb\xdb\xee\xd7\xda\xd6\xd4\xd9\xe9\xcc\xdc\xf0\xd6\xda\xea\xd7\xdb\xeb\xda\xdc\xd9\xd2\xde\xec\xdb\xde\xda\xd9\xdd\xed\xd4\xe0\xee\xdb\xdf\xef\xde\xe0\xdd\xdc\xe0\xf0\xd6\xe2\xf0\xdd\xe1\xf2\xd7\xe3\xf2\xe1\xe3\xe0\xdf\xe3\xf3\xe3\xe5\xe2\xda\xe6\xf4\xe1\xe5\xf5\xde\xe7\xef\xe5\xe7\xe4\xdc\xe8\xf6\xe6\xe8\xe5\xdd\xe9\xf7\xe6\xe7\xf1\xe0\xe9\xf1\xe1\xea\xf2\xe8\xea\xe6\xe2\xeb\xf3\xe9\xeb\xe8\xe3\xec\xf4\xea\xec\xe9\xe5\xee\xf6\xec\xec\xf7\xec\xee\xeb\xed\xed\xf8\xe7\xef\xf8\xe8\xf0\xf9\xee\xf0\xed\xe9\xf1\xfa\xef\xf1\xee\xf0\xf0\xfb\xee\xf3\xf6\xf1\xf3\xf0\xf4\xf2\xf6\xef\xf5\xf7\xf2\xf5\xf1\xf0\xf6\xf8\xf4\xf7\xf3\xf2\xf7\xf9\xf3\xf8\xfb\xf6\xf8\xf4\xf4\xf9\xfc\xf7\xf9\xf6\xf5\xfa\xfd\xf8\xfa\xf7\xf6\xfb\xfe\xf9\xfb\xf8\xfa\xfc\xf9\xfd\xfb\xff\xf7\xfd\xff\xfb\xfd\xfa\xf8\xfe\xff\xf9\xff\xff\xfc\xff\xfb\xfe\xff\xfc\x1d\xe0k\xdb\x00\x00 \x00IDATx^\xed\x9d\tp\x14\u05f9\xef}\x93\xdc\xfb\xde]t2\xaa\xbe3\x12\xd2\x13TI\"b\xb9PzFU\xc0Ř\xb5j\"\x95)!\x97\x8b\x87\x1d+U\x02\xa2\xd8O@L \x18\xa1g\f\x97\xa4,,\x16\x13H\xbc@t\xcbv\n\xd9\xd8V\x99'{\xd8\\Pl\x97\xe0`\x85\xb2͢\xc8\x06\x83\x1fKر@\bMթw\x96\x99\x9e\xd33=\xea\x99Ѩ՟\xfa\xfbE\x91z\xce|}\xba\xc7\xfa\xe9\xcc鞦\xff\x0fQ\x04\x01\xc1CV\x05\b\xe2\fPU\x04\b\xa8*\x02\x04T\x15\x01\x02\xaa\x8a\x00\x01UE\x80`\xa1j\x1b\x828\x04T\x15\x01\x02\xaa\x8a\x00\x01UE\x80\x80\xaa\"@@U\x11 \xa0\xaa\b\x10PU\x04\b\xa8*\x02\x84$Tm\x988X\xcb\x1d\xf3\\\xbc\x9e\x12c\n!\xa4\xdc\xd02\x8c\xb5l\x89S\xfd\xe9\xfbq\x9e\x88\xc3H\xd6\x17\xf9ȪJ\xe2g\xa5\xb5r\xf1ͪ\xe2<\xcdW0m\xe9\xe1\x1e\xd7@\xfa\x95\xc4U}\x96\b\xfcq\xbbJ\x88dT=\xbdj\xc8\"\xd3'\xe2\xf1\x8e\xd8\xc3j\xab2\x89\xae\xea\x81i$L\xd6*\x8b\x95\x90\xfe#aU\x0fg\xc8\xdf\xe6\xc2\xf8}%B\x12\xaa\xbe_BHr\xaa>%\xf6p\xc8\xe7Vu\x82\xb0\xaa\x9f\x16\x13\x85eV\xab!\xfdEªna\xbfnj\x15\u007f\\\xbf+~_\x89\x10\xab광#G\xfeѬt\x06IR\xd5\xd6AR\xb7\x97\xad\n\x05aU\xe7\xf3U|\x13ʧ\xe4\xf1\x05-\xc1\xe9\x03b;\t\xab\xfa2\xfb=\x16\xc7\xef'QbU\x8dKҪ\xbe\x1c\x1a\x19'Y\x15\nª\x0ef?\xffן\xd8\xc2\xe7\v\xf9\xcas-VC\xfa\x8b\x84U\xfd\r\xfb5\x8e\x8d\xdfO\xa2\xf4\xa5\xaa\x13\xf9.\xf2\xc1\u007f\x8fU%'\xa4\xea\x01\xee\xe7\x9fdSIz\xfe\x1c\x91>!AU\xcbC\x03\x16\x19\xd9֖\xcd~\xc8#\xf3!l\x89\xbfw\x17\xb0wж\xd6ec\x06\xf9\x8a\x17|\x1aZ\xe3\xf3U~vT]\xf4ě\xc6\xed\xf50W\xdd3\u007fL\x8e\xa6\r\x9e\xb0H\x8837\xbc\xc5M\xfcсg\x8b\xb3\xbc\x85\xe5\xe19\xad\xd9\x06\xdbv\xf1\xd9\xf4G|\x90\\\x10n2\xab\xdbU5ԛ3\xe5U\x83\xaa\xafȧ^\xad\xaa\xaa\x9a/\x17\x8d\x1b\xfc\\8\xbcl\xa8\x967\x83\xff\x97(\x93\xad{\xf8\x06w\xc5V#}B\xdaT\xdd5R\x16\x14\xca\xc9\xecG#\xc3k<\xf5\xa5\xba\xbd\xf8\xaan\xca\n\xaf\x91\xc7\xe7\x8b\x06Uׇ\x9f\xf3K\xe1L6\xd8ֶ\x80=\x18#\xd6+<\x1dj2\xa9{\xd9+\x1fV\x86T=ͧ\xa8ު\xa8\xb3bQ\x1b\x14\xaa\xf2\xfeɣ|\xce\xee\x95{\xb1\x88-N4\xa9F\xfa\x84t\xa9\xaa\r\rW\x88\xb3Y{\x06\x13\x9dy\xea\xf6⪺K($O3\xe4\xb7\x1aUݔ\xa1w6AX\x18\xbbA\xe6\\!\xe1\xee\xbdϛ^\r\xf5\x1d[\xb7E\xef*\x93ȹ\xeas\xf2a^\xc5\xca\xc8\x11c\xf4\x06\xb9\xaa\x83DۊӼ?yN\x8b\xff\rԛT#}B\x82\xaa~\xb8\x85\x9fV-\u07b2\xe5\x9d8\xaa\x12R\xb0\xe2\x9dz\xbe\x90\xc9G\x16n\xa4\xb7zS\xfd\x04\xf6\xd3\U000e1cbd\xb8\xaaV\xb3\x1fU\xbbN\xb7n\xe2\x9d.c[\xdc4\x9e-<\xb1iӁ\xb6Os\xd9Ҙ\x86?\xfe\x8a\x1f\xe1\u05f6\x99nP\x9e\xa2\xc8< \x05\xfaq\xa8\xef\x98:!\x9a6\xff\x9d-O\b\xb3xg\xadcI\x98⥲\xab\x98\r~.\x9e\xce\x1c3\xccs@\x8c\xa5\x13x\x15\xff\xa3\x18\xd4jR\x8d\xf4\t\t\xaa\xaa\x1eV\x99\xab\x9aÏe\xc49xf\xf3\x87\xfc'\u007fW\xffr\f1\x9e\x93\x8f\xab*\u007f?\x16\xf3\xdaM?\x9e\xbf^\x1c\x17\xe9\x87U˸E\xfcd\xe9\x1f\xd9\xf05\xbc\xcdl\x83\x8c\n\"\x8f\xfd\xb9J\xda\x01\xd9wL\x1d\xf7\x99\xac\xe7OU\x91\xb0X\x9f\xf25C\x14l1ݠP\xd5\xc7\xd6\xdf\xce楙\xa1\x037>\xeeW\x99\xee\x1e\xd2\x17\xa4M\xd5gE\v\x1fX\xd8o{1\xe1\xd3FΖ\xe7^1\x9c\x89\x8d\xab*\xf7\xc5W\xf1\xf2\x81\xc8\x13\xba\xaa\xfc\xc8~\x85h\xe2\xe2\xf3\x89l\xcc\x06\x99p>\xb6\xf4\x1b\xb6\xb0\x87k\xb5Dv\x11S\xf7\xac\xbec\x875\xa2\x8f\x81\xef?\x95\x13vU{\xd3l\x83Bէd\xb1\xf8\xa3Z\xcc\xfe\n\a\x87\xfe;\xc4\xee\x1e\xd2\x17\xa4MUy\u07bd\x88\x88\xc9%\x9f\xdaVEoJ\x10W\xd5M!W\x86=\xb5\xa9U>\xa1\xab\xca=*\x9b\xcb\x19\x1e\xdaP\xcc\x06\xdb\xda\xfe\x0f[\xf0\x89\xf7o\xfe\x86>Bv\x11S\xf7c\xa2\x0f\xf2\xfcC\xaa\xda\xf0N\x9c~gѣ>\xb1\xfd\xa1\xa7M6(T\r\u007f\xb2\xc0\xf7\xb4\xb8\xad\xedU\x12:\xb3\x15\xbb{H_\xd0+U\xf9$-\xac\xaa<Q3R\x1a1\x89\xfd\x98\x1f\xbd)A\xfc3\x00\xe2\x1dY\x90/Ǩ\xb0\xaa_\x12\x03\xb5m&\x1b\x94#Zn9g4\xaf\x92\xe7\xc8b\xea\xf8\xdcy\xb1\xdc\xee$\x125\xb3lm\xe0\xbb\xc2\xeac7(T}'T\xf7%?g\xf0\xa1x\x1b\xe0\xeb\x9b\xec\x1e\xd2\x17\xf4JU~\x8e&\xac\xaat\x83\x0fU!U\x9f\x8dޔ\xa0\x87\xf3\xaa\x9b&z¿oq\xf9VX\xd5V\xa3\v\xbc)f\x83rv\xacP!\x9e\x8d\xa9\x9bH\xf4\x8f\x15B\xaa\xbe\xbc\xa8jF\xf8\x84\xc1\x01>\xb0.3٠PU\u007fk\xe7\x1f\xc5\xceoe\xb5\xde?\x99\xef\x1e\xd2\x17\xa4\xa0*\x9f\xf6\x89\xdf\xff\x97\xfc$\x8d\xa9\xaa|\xc4yB4\xb4~d8\xad\xda\xf3\xe5*\a^~B\fl\xc4\xcb\xe7\x00\xfa\x04\xc0\x17\xa9\b\x11\xabj\xb5Q\x98\xd0\\ \xa6\x8e\xf7\x19\x9as\x8e&B\xd5\x12u\x87\xf8\xd8\xfb\xac\xc9\x06\x85\xaa\xfag`\xfc\xb3\x86\x91\xaf\xe8\xeb\xc5\xee\x1e\xd2\x17\xa4\xa0\xea\xe0\x90\x1dr$3U\x95\x1fV\x15\x88S\x8c\xbf&\xdeb\xf5c\xf5\xf8\xaa\xb6n\x97\x9fK\xf1uŨ͵\x12\xc3+\u007fo\x97\xc7I[B\xba\xc4l\xf0\xcb|\x12\xc5\n\xd3:~\x12u\xa4h\xd8Ç\xf0Z\xe9\xb8\x16:\x9d\xb6\x8b\x1fj-3٠QնG\x89\xfc\x04W\n\x1a\xbb{H_\x90\x82\xaa|\xe8\x11\xf6\x89\x93<\xa6\xaa\n\x89\u007f\xc5\x1e\u007f\xce\x1b\u0087Μx\xaa\xee\xe2}D\xa6\x15\x1f\x86\xba\x17\xb3\x88\x85la0\x1f%\xdf!${\xec\x01\xb3\r\x8a\x832\xfd\x13'~\xf2\xf4\xe16\xb3:qҊ[|\xba\x8c/Նv\xb5@|\xb2\xfa\xfe\b\"7\x1d\xb3A\xa1j\xe4\xe4D躘Їb\xb1\xbb\x87\xf4\x05)\xa8\xca\x15\xf2,|\u007f\x8b_\xfc\xbeLUm\x9bƟ\xf2\xd7.*\x0e\xfd\xf2u\xb8\xaa\x85\xe5:[\xf4Q\xb5X\x18s\xb8\xf5C~r>\x8fK\xc0\xaf>͙\xff\xd4\u007f\xca)d\xf1\xab\xbb^\xe1\xdb\x11g\xdfc6\xc8ŋ\x9c\xd2\xe4\xf2\x90\xed\xa6;Ƈ@\xf2D\xc3o\xe4y\xffڶ\xf0\aq\xf9c'ɹ\a?5\x1b\xb3\xc1(U?\xcf\x15\xa5\xa1Kwcw\x0f\xe9\vRP\xf5U\x12\"\x93\x8fB檪\x1f\xac\x1a\xaeʟB\f\xd4ꪾ\xefS\x9a\xf9Ǖm\xb5z\xc9\xca\xc83Y\xc2\xfb\xe8\r\x8a\x93\xa4\x91\x8b\xbeŅ+\x95\xa6;\xf6\xa1\xbe\x99a\xb2\xef\xb6\xc3\xfa\xd5\n\x9c\"!d\xf4\x06\xa3Tm\x9b\xc7\x1f\xeb\x17p\xc5\xec\x1e\xd2\x17\xa4\xa0j\xf8\xe3\xf9\xac\xfaY$\x9e\xaam\x1f\x8d\b\xff\xf6\xaa\f\x1f\x8b\xc7U\xb5\xedͼp\xa3W\x9e\xac:,\xcf\xcbs\xd3\xeb\u0082\xe5ɋ\xb0\xa37\xc8?0\"\xcaG\r\xfc\x9cTN\xab鎽\x19\xba\xfezn\x1d\t\xff\x83\x952\xa23)\xd4I\xd4\x06\xa3U\x15\xb3\x86\xc8e\xb1ѻ\x87\xf4\x05\xa9\xa8\xda\xf6ʣ\xb9\xdea\xf3\xf6\xb4\xf5\xa0j\xdb\xe7+\xa7\f\xd6|ß\n\x9f\x8d\f\x11_ն\xd6\x15S\xf2\xbcZ\xee\x98g\xc3\xce}T>X\x1b<It\xb7g~qn\xe6\xa01\x8bBW.Eo\x90\u007f\x1f\xa3l\x85\xef,?\x19o\xb6c\a\xe6\x16y\x87\x94\xbd٦\xab\xcaF\xf4\xb9c\x06k\u07bc1\xf3\xfeS\xef\xc1\xb8\xc1hU\xdb\xf8\xf5\t\xf5\x91\x87Q\xbb\x87\xf4\x05\t\xab\x8a \xfd\v\xaa\x8a\x00\x01UE\x80\x80\xaa\"@@U\x11 \xa0\xaa\b\x10PU\x04\b\xa8*\x02\x04T\x15\x01\x02\xaa\x8a\x00\x01UE\x80`\xa1*\x828\x05T\x15\x01\x02\xaa\x8a\x00\x01UE\x80\x80\xaa\"@@U\x11 \xa0\xaa\b\x10PU\x04\b\xa8*\x02\x04T\x15\x01\x02\xaa\x8a\x00\x01UE\x80\x80\xaa\"@@U\x11 \xa0\xaa\b\x10PU\x04\b\xa8*\x02\x04T\x15\x01\x02\xaa\x8a\x00\x01UE\x80\x80\xaa\"@@U\x11 \xa4]ՉdIlc\xfb\xbd\xd86+V\x90\xa7\xadJBE\tU\x9a\xd3@ʭJ\x10\x87`\x87\xaa\xc1\x95\xbe\xebf\xa5=\x93\x90\x80\xa8\xaa{\xb0C\xd5\x0eBPU\xa4\xb7\xa0\xaaV%\x88C@U\xadJ\x10\x87\xd0\x1bU?~O\xe7\xff\xea\x8dR\xd5\x06Rw\xa9\xba@+\x9a\u007f\x89\xd2\x1a\x11\xfbs\x84\xb5\xb6W\x17i\xb9e;xY=Y\xb5c\xb8o\xec)\xb5\x90\xb1\xbd\xa2@\xf3\x8d^p\x81F\vx\xe2\x99aZ\xee\x8cݦE\xc6ʝe\xf9\xbe\xf1M\x87Ȥ\xc8F\f\xab4\x90\xda\xe3\xe59\xd9\xe3_\v\x8a\a\xe5\x17\xf8\xe6\x17\xa6\xf0\xb7\x84\xd8KoT}\xe4\xefu\xfeMo\f\xabZ]@\xb2s\t\x19\xddA7W\x10R^\xd1N\xe9\x8e,\xe2}\xb8\x88\x90Ŕ[T\xed%$\xabC-\xa4\xb4\x8a\x90\x82\x92<\xf6\xedr\x94\x80M>\x92]\x92OH\x93Y\x91\xa1\xb2\x81\x90\xfc\x12\x8dTHU\xe5F\f\xab0;\xb35\xff\xa3\x1eR\x19\xe4\x0f\x1e\xce#\xf9l\xf3\xc5\x1d\x14q6\xbdQ\xf5\xcc?\xe8\xaa\x1e\xd4\x1bê\x92Ql\bl\xd2\xc8\x06}\x02ОMj\xeePڒK\x1a\xb9E\x9e\xe1M\xcd\x1b\x8c\x85\xcd\xc4LJ\xdc@6Yi\x14\xf0\xebl\xb2\xa0\x83\x06k\x89\xf7\x92I\x91Zy\xd4C\xea\x83\xf4\xf2\f\"U\x95\x1b1\xac¶8\xfc$\xa5\ar\xc9F\xf1`\xd8>J?\xd0\xc8f\x8a8\x9bި\x1a\x19V#\x83jDտ\xf0GU\xa4JW\xb5\x86\x94\x89\x8a7\xc8(n\x119F\xa3\vk2\x16\x89\x8a\x1a2\xc7(\xe0\"\xe2\x0fu\xbeޤH\xad\x9cEj\xf8\x8f\x8eaRU\xb9\x11\xc3*l\x8bG\xf9\x837H\x91x\xd0\xca\x1f\x88\xcd#\x8e\xa6W\xaa\xea\xc3jdP\xd5U-\x16\x8fV\xf1Ö\x90\xaa\x85\xe4m\xd1\xd6\xe1!\xa7\x98EE\u2061\x90ޓo\xc3\xcbȓF\x01\x8bC\xab\xb6\xb7\aM\x8a\x94ʮl)'k\x13\xaaʍ\x18Vi \x13d\x9b\x97\x1c\xd77_\x8f\x87W\x8e\xa7W\xaa\xd2\u007f\x8f\x19TuU\xe5\b\xba\x9e\xcc\b\xabz\x8bM\b\xc7\v4\xd2\xccܐ㤡\x90\x95\xeeް\xb8b(!\xb3\x8d\xaajr\xec\v\x11]\xa4T\xb6\x93̠Xh\x96\xaa\xfacWi\x90\xe3.\xf7\u007f;{ +6ꕈS靪_\xfcC\xf4\xa0\xaa\xab*G\xa9\xf5\xdcD\xa9\xeay%\x05\xb8\x91YT!\n\f\x85\xc1U\xecȉd\x94L\x88R\xf5\x0e!\xed\xfa\x06b\x8b\x94\xcaC$K.|\"U\xad\x88]\xa5\x81,\x95%\xe3\xc8\x1b\xfa\xe6QU\xe7\xd3;U\xe5\xb0\xfa#\xb5%\xae\xaa\xd7\t9\x11)3U\xb5\x96dTn\xde\u007f\x8b\xd6E\xa9\x1a$\xec\xbd:Ll\x91Ry\x82d\x18FՊ\xd8U\x1a\xc8\x02Y;\x9a\r\xee\xa8*\x1cz\xa9\xaa\x18V\xd5A5\xbe\xaat\b?\xf2紜\xec2U\xf5A6;j\xe2TGO\x00\x86\x8b\xb3T\x94\xbe=m\x95I\x91R\xf9\xc0\x1b\x9a\xab\xaeTT5\xae\x12~Ͽ\xa3\xb1\xa1\x1aU\x85C/U\xe5êaP5S\xf5\x1e!\u007f\xa3\xfc(\xbbD\x8cx\xdb\xf9)'3U/\x84\x06\xcf[\x05\xfcIU\xd5\x1a9\x93\xa5e\xa4֤H\xad\xac\x90cfW\xb1\xa2\xaaq\x95\x06\xa2\xb5\xcb-\x97PT\x15\x10\xbdU\x95\r\xab\x86A\xd5LUvT\xd4x\xa7\x8b\x1e\xf7\x9297\xd9,2\x97T\x9bO\x00\xba\x06\x91\x1a&\xf3Y?\xe1k\xa9\x02\x9e\xf6\x91e\x0fh\xb0\x8ed\x9d7)R+\x0fgx\xd6\a\xe9\xcd'\x89\xa2\xaaq\x95\x06BJ\x98\xab\xdb}\xec\xfd\x1fU\x05DoU\xa5\xffn\x1cTMU-a\a5\xcd\xe2<\xbf\xb7d8\x93\xa8#\xce\\\xb5\x9e\x90\xa1\xfe\xb1\x9e\x9cE\xe4\xe1\xe8O\xab4\x92S\x92K\xb4&\xb3\"Ce=\xff\xb4\xcaG\xc6q\xf7\xc2\x1b1\xac\xd2@\x86y3K\x86\x11RKQUH\xf4Z\xd5/\x8c\x83\xaa\xa9\xaa\xc7'zs\xde`?O\xfc\xacH\xf3\x95\xac\xe2\xd7Y\x9b\xaaJ\x9b'\r\xf1\x8e^t首\xd1n\x14\x90\x1e\xaf,\xc8\x1cR\xc1/$\x88-2V6\xfb\ay'47\xf0)Cx#\x86U\xd8\x16\x8f\x94e疵\xa8\x9bGU\x9dO\xafUu(+ȼ8\xcf\xe0\xc5T@\x19h\xaa\x96\x95\x04\xc4ωd]\x9c\nT\x15(\x03M\xd5\xf9☩c1ɽ\x1c\xa7\x02U\x05\xca@S\xf5B\x11\xc9\x1cU\xec#Y\xcd\xf1*PU\xa0\f4U\xe9͕%\xb9\xbe\x115'\xe3\x16\xa0\xaa@\x19p\xaa\"\x03\x15T\x15\x01\x02\xaa\x8a\x00\x01UE\x80\x80\xaa\"@@U\x11 \xa0\xaa\b\x10PU\x04\b\xa8*\x02\x04T\x15\x01\x02\xaa\x8a\x00\x01UE\x80\x80\xaa\"@@U\x11 \xa0\xaa\b\x10PU\x04\b\xa8*\x02\x04T\x15\x01\x02\xaa\x8a\x00\x01UE\x80\x80\xaa\"@@U\x11 ؤ\xea\xc5o/^\xb9ml\xba}\xe5\xe2\xb5k\xdd\xe6\xe5\b\x12\x83M\xaaF\xf8x\xed\x15\x8a\x82\"\xc9c\xaf\xaa\xf7)]\xfd\xd8_\xf9\x0f\x04I\x12{U\xa5\xfc}\x1f\xc7T$\x15\xecT\xf5\xfe\xfd\xce\xfb\xf7\x0fn\xbb\xc6~t\xa3\xafH\x92ة\xaa`u\xe99\xab\x12\x041\xc1vU\xbb\xafXU \x88\x19v\xa9\xca\xde\xf0\xbf\xd8\xf6۵kּ\xbe\x8d}[\xfb\xd6{\xdfY\xad\x81 \x06\xecR\x95\x1d\xf4\xaf}\xbct\xfa\xe4ɓ\x1fa\xff\x9f\xfe8\x9b\x06\xe0y\x00$\x19lT\xf5\x85\xc9\x1f\u007f\xf6\xe7\xcf\xfe\xcc\xf8\xec\xb3_N>\x83\xaa\"Ia\xa3\xaa/\x96\xde\xd5\x1f\xae)=C;)ڊ$\x8e\x9d\xaaN\xffB\u007f\xf4\xc2\xf43=U#H\fv\xaa:UW\x95.GU\x91$\xb1Q\xd5\xe5\x8f\xdd\xd8\xf6\xa3\x1f\xfd\x1b\xfb_\xe9\xfd\xdfN\xbf\xb8wm\xe7\xc15\xca\xf5\x00G<\x84\x90\xb9\xfa\n;\xf2\x9aL;\xb2\xa0\xde\xfbk\xb3\xe6v\x8d\x14\xf3\x9fGg\xe4\xe7Lk)\xd9mV\x838\x1b\x1bU}~&\xfd\xe5\xf7\xfe\xee\xfb\u007f\xf7\xfd\xef\xfd\xf7\xcemSo\xbf\xfe\xd8\xed?\x94*\aW]\x9f\x8c-\t\x9c\xd7W\xf8 \xfb\xed\xd8^Z\x0eŶ\x19)\xd1J̚\x83\xfb\xaa4\xf6\xe3\x90V\xde\xf4F\x05\tGh#\x90\xb0Q\xd5\x17J\xbf=\xb7m\xdb{\xec\u007f\x1fӗ\xa6\x9e\xbb\xf2Y\xf7\x95/:\xd5\x1a\xbf!<2Hc\x99\xf0\xa4I\xa3\xca\x1dO\xa5\xe7\x96\xe93u\\\xd52?\xeb5X\x85\xaaB\xc4FU\x95\xb9j\xb7\xe9\\\xd5o\x99s:~\xb6EA\v9DZL\x9f\x11\xaa\x0e\xe7\xf9\xaf\xf4(Iin\x81\xf4/v\xaaZzN\xceLٷ\xff\x98z\x86ލ>Y\x15Q\xf5\xba\x8f\x10\xcfV\xb9\xbc\xb3\xacH˟1,H\x9b\x88d\x1co\r\xbe\xf6hv\xf1\xc2\x0eJ\x9f!\xda\xc6\x05\xc5YegEq\xddPZ\xc8\x13\xa9\r\xad\xdfT\x16\xe6\xce\x12\x13\x80'\v\x8e\xf1u\xb7\xdfR{8\x92I\xc8\xd2S\x95\xc3}e]\x8d\xac\xfb:ZG\xc4\x14A/@\x1c\x81\xad\xaa\xde\xd0\x1f\xae)5\xf9\b@\x19U\x0f\x05\x02\xde:\xb1t \xa3\xf2\xed\x1d\x1b\xf3I\x17\xbd\xb3;0zZ \x108\xc1\x9b\xe7yj\xb67\xe4\x8d\x0fҿl\xcd$yu\xbfΑ\x19\xd5\xfeYt6\xefEm=\x95S\xbc\xb9\xa9\x8cpUۋ<eu{\x1ePC\x0f\x1d\x8d[\x87\x8d\x1eT\xb4\xa02\xe3\xeb[;s\x96]\xa2\x97jsw\xdeR\n\x10G`\xa7\xaa3\x9f\u007f\xe9\xc5Ռ\x17W\xbf\xf4\x93GL.\xb06N\x00|R\xd5uy]\xfc{\xae0F\x9f\x00\xbcK~Ǿ\xef'|\xe4\xd5r\xcfRZ\x99Ǜ\x83\xd9\xf5\xb4>[\x94FZ\xa7\x8cb#c\xb0\x84\xabJ\xaf\xae\x98\xa0\x91\xdcƨ\x1e\xe8x\xe2\xbfI\x837\xd9\xd2<>\x1b\xae\xfcYt\x01\xd2\xffب\xea[?}\xact\xaa\xa4\xf4\xa7?\xbf\x98\xa0\xaa\xe7\v\x87\xd7l<\x1c\x94#\xa1\xae\xea\x93#\x1et1\x86\xf2\x93[\xda\x1c\x1a\x9a\x8a\xd2#dw\xc7nr\x84\xaa\xad\xd7\xc9F\xfex\xa9\x16Z\xf5ގ2\xb2\xdd\xd8\x03\x1d\xaf}\x1dz\xb6\xc5\xd7A;\xb2Z\xa26\x818\x00\xbbTe\xdc8w\xe6\x8b0\xe7\xbe5\xb9\xb6\xdaTUz}\xc3\xecb\x92\xbf\xca8\xaa\x96\x84\xe6\xad\xfc\r^\xe3\x85R\xd5\x06\xd1\xd8@\xd5\xd6CDĮ\x8b\x82\xfd\xdf\xf0\xc5\xe0\xa4rc\x0ft\xfc\xb8\xf0V\xbb\xf2\x9bhS~0j\x13\x88\x03\xb0QUK\xa4\xaa\xb7\x96]\x15\x8fB\xaa\x1eZ̼\xb9\xbeշ\x8e?\x10\xaanf#`\xe5\x88C\x02\x9e\xa4\xae\xa8:k\xdc\xfe\xfd\xfb\xc7͢j\xeb߈Xu\x0e/(\xa8\x11}.\x19e쁎\x9f\x15\xde\aZSA+D\x95\xa1\x00\xe9\u007f\xecT\xb5\xbb\xfb~\x98n\xb3\vU\xa4\xaa\x87\xc9N\xf1(\xa4j\x1d\x11q\xe9\xfe\xeap\xc5%~t\xde,O\x8d.YI\r\xaa\x16.d\xdf\x16\x14RC\xeb\xc4\"\xe6\xfeI/_\xcc/\xe4\u007f\x06An\xa6ڃz\x12l\x8f\xf7\x82w\x0f_0\x14 \xfd\x8f\x9d\xaa\xf6Lמ\xb1%\xec\xf8>\xb0\x81\xbda?\xf8$\x10\xf0V\x05v\xde\xe4\xaaf\xd7~\xd04W\x9e-\xad\xd3\xea\x9b\xfc\xd9\xfc#\xad\xc5\x19O\xbf\xcdZߠ\x17\x02Zվ\xe0\xe1*-p\xa1\xa3\x99,\xb9C\xef\xfc\x8a4\xdfSZ鱬\xa2\xba\xa5\x83=\x99\xbf;N\xf3IAms\x93\xdfwR\xed\xa1k\x8f8\xb3\xd0.w#XXV(\x0f\xfa\xf5\x02\xc4\x118Gգ\x9e\xd0\xe4\xd0w\x82\x1e\b-o\xa0\xf4\xb5iuEZ\x81_\x9e\u05ffW3\xd87m\xbfXl\xf6\x0fɝ\xd2\xccϠ\x12\xa2\xb5f\xb3\xef\xcf\xec\xc8\xe0\xe7C\x9b\b\xc9ء\xb4Rz\xaa|\xf0\xf0\xe7~\x97\xc9\x16'l^R\x9c\x9dWq\xd2\xd0\xc3\x11\xb9\xb1\xf2\xd0~\xd4k\xf5\xa1\xa5p\x01\xe2\b\x9c\xa3*\x82\xf4\b\xaa\x8a\x00\x01UE\x80\x80\xaa\"@@U\x11 \xa0\xaa\b\x10PU\x04\b\xa8*\x02\x04T\x15\x01\x02\xaa\x8a\x00\x01UE\x80\x80\xaa\"@@U\x11 \xf4\xb3\xaa\x18\x12\x84$J?\xab\x1a\x01C\x82\x90\x9eq\x86\xaa\x18\x12\x84X\xe2\fU)\x86\x04!V8AU\f\tB\x12\xc0\t\xaa\n0$\b\xe9\x19Ǩ\x8a!AH\xcf\xf4\xb7\xaa\x18\x12\x84$H\u007f\xab\x8a!AH\x828@U\f\tB\x12\xc1\x01\xaabH\x10\x92\bNP5\xa1\x90\xa0\xa6G/\xc5y&U\xaeN\u009bWC\xc2\t\xaa&\x12\x12\xb4\x8a\xd4Eݓ\xb7\xd7a)\xc1U\x9e\xd8\xfbQa\u038bcq\x80\xaa\x16!A\x82\x06\xcfkQ+\xa6#,e{fCt\x13\xe6\xbc8\x16\a\xa8j\x11\x12\xc4i\xd3\x16\x87\x17/\xfb\xe5]$\xd3\x12\x96\xb2L;\x1bӆ9/\x0e\xc5\x01\xaaZ\x86\x04Q:\xb7@O\x8f8F\x8e\x89\x9fi\tK\xb9S\x10{Oj\xccyq(\x0eP\xd52$\x88>\x18\xb4H.4\x8c~\xf7\x049\xb1}\xf4\xfaT\xc3R\x94\x02\xd1\xe12_L\x82\n\xe6\xbc8\x14'\xa8j\x15\x12D\x0f\xcb{\xa4\xf3_7y\x98\x94\x90Y\xe7S\rKQ\nĚ\xbb\xc9\x1e\x1a\x05\xe6\xbc8\x14G\xa8j\x11\x12D\xb7\x93\x93\xe1\xc5f\x8dh\U000969e9\x86\xa5D\n\x18gI\xcca\x13\xe6\xbc8\x14'\xa8j\x15\x12\xc4\xdetC\xb7\x94\xbe\xba@+$\x85\xde\xe7\xfe&\x1f\xa6\x14\x96\x12)\xa0\\\xd5F\x1a\x05\xe6\xbc8\x14\a\xa8j\x19\x12D\xf7\x91O\xe4ª\xfc\r\xc7\xc9_\x1a\xf2W\xf6\",%R@\xf9p\x15sr\x13s^\x1cJ\u007f\xabJ\x13\b\t\xa2\x1dZH\x18\xfa\x80\x1e#\xc7\xe9\x83`/\xc2R\x94\x02\xaeN\xccI%\xccyq(\x0eP5\x01f\x8d\xd2\x0f+\xce\xe7\xca\x13\xf4)\x87\xa5\xa8\xa7\x9a\x82\xc5\xe1\x04\x00ھ\xb2M.`\u038bCq\x82\xaaV!A\x94\x9e\xf0\xc4|P\x99ZX\x8a\xb1\x80\xd6\x13\xfd\x83\xa7\n2\x83\xff\xc0\x9c\x17\xc7\xe2\x04U\x13`\x997zN\x99ZX\x8a\xb1`\xa7\xef9\xbd\xbf\xcdy\x1b\xf8\x0f\xccyq,@T\r\xce\xd7\x1a\xadj\x92\xa6Q\x9b\xdbeU\x838\x06 \xaa\xd2`\xfd\xd0t\x1fY\\-X\x89'\xd6\x01\x01EU\xc4\xf5\xa0\xaa\b\x10PU\x04\b\xa8*\x02\x04T\x15\x01\x02\xaa\x8a\x00\x01UE\x80\x80\xaa\"@@U\x11 \xa0\xaa\b\x10PU\x04\b\x0eU\x15\x93W\x90h\x1c\xaaj\x04L^A$\xceV\x15\x93W\x10\x1dg\xabJ1y\x05\t\xe3dU1y\x05Qp\xb2\xaa\x02L^A$\x8eW\x15\x93W\x10\x89SU\xc5\xe4\x15$\n\xa7\xaa\x8a\xc9+H\x14\x0eV\x15\x93W\x10\x15\a\xab\x8a\xc9+\x88\x8a\x93UM(y\x05q\vNV5\x91\xe4\x15\f\tr\r\x0eV5\x91\xe4\x15\xdbB\x82\xd2\xd0/\xd2;\x1c\xacj\x02\xc9+\xf6\x85\x04\xa5\xa5_\xa478X\xd5\x04\x92Wl\f\tJK\xbfH/p\xb0\xaa\xd6\xc9+v\x86\x04\xa5\xa5_\xa4\x178YU\xcb\xe4\x15;C\x82R\xeb\x17I\x1f\x8eV\xd5*y\xc5ΐ\xa0\xd4\xfaE҇\x93U\xb5L^\xb15$(\xd5~\x914\xe1`U\xad\x93Wl\r\t\xa2)\xf6\x8b\xa4\t\xa7\xaaJ\x13I^\xb13$(\xe5~\x914\xe1`U\xad\xb13$(\xe5~\x914\xe1dU\xad\x93Wl\f\tJ\xb9_$M8YUk\xec\v\tJ\xb1_$}\xc0Vվ\x90\xa0\x14\xfbE\xd2\apU1$\xc8=\x00W\x15C\x82\xdc\x03tU\x11׀\xaa\"@@U\x11 \xa0\xaa\b\x10PU\x04\b\xa8*\x02\x04T\x15\x01\x02\xaa\x8a\x00\x01UE\x80\x80\xaa\"@@U\x11 \xa0\xaa\b\x10`\xaaڍ!A\xee\x03\xa6\xaa\xf7)}i&\x86\x04\xb9\v\x98\xaa2:\xa3\xc2\x02\x91\x81\x0eLU\xd9;\xff\xde\u05ef\xe1\x04\xc0U\xc0T\x15'\x00.\x04\xa6\xaa\x14'\x00\xee\x03\xa6\xaa8\x01p!0U\xc5\t\x80\v\x81\xa9*\xc5\t\x80\xfb\x80\xa9\xaa\x9c\x00tw\xd2\xee\xfb\xfc\v\x87W7\x00S\xd5\xd0\x04\x00q\x130Uet\xde\xe8y(Ő\xa0\x81\x06LU\xf95\x00o\xdd\xdf\xfbR\xe7\xde\xd5\xec\xeb\xee\xc1\xb51\x15\xb6\x85\x04U\x11B\xb2NŶ\xab\xfc\xad:\xdf7\x03o\x83\xd1K`\xaa\xca\xefi\xfd\x93\xef^\x9fy[|\xdd\xd8\xf6\x93\xe8\x02\xfbB\x82\xce\x06\x02\xeb·y\x8d\x87\xbf`\xc3\x1c\xdf\xf5\x9ek\x10+`\xaaʸ\xfb\x1d\xbd\xf6\xd7\xd0\u05cdsQO\xda\x18\x12D\xf9}\x83{V\xf5*i\xa0\xc1\xe8\xfb\xb5\"\xc9\x02SUq\x06\xe0J\xfc\xe7m\f\t\xa2֪\x9e\xea\xddF\x11\tLU\xc5\x19\x80\xaf\xba\xef\xc69YegH\x10UT\r\xae\x1f\x975v\x9d\x98\x94^\xae\x1c2t\xe1\xc2!ٍ\x0f\x86ț\xad/\x88]\x0fI\n\x98\xaaҞ?\x02\xb03$\x88*\xaa\xceіn_\xaaU\xb1\xa5\a\x0f\x17\xac\xab\xf5\xfa6\x97\xd5\xd3Á\xad\xa4.\x10\xb8\x10\xbb\x1e\x92\x140U\xb5\xb8\x06\xc0\u0590\xa0\x88\xaaͤ9\xfc\xbd\x91\x1c\xa1t\x1d9.\xdaq\x02\x90\x16`\xaajq\r\x80\xcd!AaU畈\x1f\x0f\xb3auq.[8\x19R\x14UM\v0U\xa5=O\x00\xec\f\t\xa2\x11U'\xc9\x1b\xad\x97O\xa4\xb4>\xe32\x1f_\xe5\x11\x1d\xaa\x9a\x16`\xaaj1\x01\xb03$\x88FT\x9d;\x82{\x1e\x1c>\x87ү=e_\x1f\x19=I\x9e\xf6GU\xd3\x02LU\xad.\x02\xb41$\x88FT\xdd.&\xb7[\xf9\x1c\xe3\x10\xc9'\xc4\xff\x8d|\x1eUM\v0U\xa5\x16\x17\x01\xda\x18\x12t\x9e\u007fZU\x1f\b\xf0\tm\xa5g\xf1\xbb\x8b=\x95l\xe9\x90w\xc7\xf6\xc07\xa23y\x06`\x1f~\xae\xda[`\xaaj\xf9\xaf\x00\xec\v\t\x9a\x13\x9a\xd7\xf2\xd3\a\xc1\x86\x92\xac\x12q^u\xb7\xc6۴i\xc7\xe8\xbd\\\xf1t\xe6\t\x8a\xf4\x0e\x98\xaaZM\x00\xfa;$\xe8Rv\xf5\xa5\xae\xae\xeb\a*\x06\xe3'\xffi\x03\xa6\xaa\xd4\xf2_\x01\xf4oHPS\xae\xac\f\xe6c\xccZڀ\xa9\xaa\xe5\x04\xa0\x9f9䑧\xa9\x8ey\x0e[T\"\t\x03SU\xcb\t@?\x13\x9c\xeb\xabnli\xac\xf6U':\x0e#\x96\xc0T\x95ZN\x00\xfa\x99`SY\xa1VX\xf6.\x9a\x9a>`\xaa\xea\xf4\t\x00\xd2\a\xc0T\xd5\xe9\x13\x00\xa4\x0f\x80\xa9*u\xfa\x04\x00I?0U\xc5\t\x80\v\x81\xa9*N\x00\\\bLU)N\x00\xdc\a\xaa\x8a\x00\x01\xa6\xaa8Wu!0UŹ\xaa\v\x81\xa9*\xc5\t\x80\xfb\x00\xa6\xea\xb6\xce+w;\xef\xdfg_{_\xbf\xc2\u007fܧ\xf7\xef\xde\xed\xbck\xb5\x1e\x02\x1f`\xaa\ue95d\xfc\a{\xe7\xff\x8f\xd238\x01p\x15\xc0T\xedԗ\xae\x9c\x89,#n\x00\x98\xaa\xfc\xa0\xff\xe0\x1fV\xbf\xb0|\xf9\xf3\xbf\\\xbe|\xf9\v\xbf\u007f\xeb6\x9e\ap\t\xd0Te\xef\xf9k\x1e/e̔ߧ\x9e\xc3i\x80K\x00\xa8\xea\v\x93\xf7~u\xe6\xab\xef\xe8\xc53_}\xf5\xfcd\x9c\xb1\xba\x05\x80\xaa\xbeX\xfa\x1d[x\xef\x17\xfc\xe1\x9a\xd23\xddw1\xb6\xc2\x15@Tu\xfa\x17l\xe1_\x1e\xda\xcb\x1e-\x9f~\xc6j\rd\x80\x00RU\xae\xe7\xffx\x88\v\x1b_U\x8c\xad\x18h\x00Tu\xf9\xcc\xdb\u007f\xf8\xd7\x1f\xfe\xb7\xef\xfd\xf3\xbf\xfe\xcf\xfb\xafO\xbd\xf2\xf1\x8b\x9d\a_\x8a\xa9\xb3-\xb6\"\x01\x8e\x97e\x17T\xb6\x14\xa4\xfbO\xc7m\x00T\xf5\xf9\x99ݿ\xfc\xc1\xf7\xbf\xf7\xd0\x0f~\xf0\x8f\x9doM\xbd\U00047677\xfb3\xb6\u009a\xe6\xec\t\x1b\xb7\x96\x10\x82\xf7W\xe9\x1d\x00U}\xb1\xf4ܕ\x83\a\u007f\xf8\xfd\xb5\a\xffLWO\xff\xea\xc6W\xf4\xf6\xb7QU\xf6\xc6V\xf4\xcc՜\x8a{\x94\xde\x19\x85\xaa\xf6\x12\x88\xaaN\xfd\x8c-\xfc\xf0!6K\xed^^j:W\xb57\xb6\xa2g\x16\xfb\xfe\x1f\xffQ\x8f\xaa\xf6\x12\x88\xaa\x96^d\v\xa5\xffą]=\xdd\xecd\x95\x8d\xb1\x15\xcf\x10m\xe3\x82⬲\xb3T\xed\xb7\x96u\xb3\x95neߗ\xd1Q?\x13\x85\x97\xeb\xef)\xb9\x16\xcaj\x86\x1e\x90\xf8\x80T\xf5\x9a\xfe\xf0%ӋVl\x8c\xad\xf8\xcb\xd6L\x92W\xf7\xeb\x9c\nC\xbf\x97\x9e~\x94usk\xf7\x94\xca\xcb\xf7<\xe1\xbb\vR%\xd7BY\xcd\xd0\x03\x12\x1f\x88\xaa>\xfe\x8b\xe5\xcf?\xbf\xe6\xf7\xec\xdb\xf2\xc7\x1f1\xbb\xc0\xda\xd6\xd8\n-\xf7,[-ϸ\xdak\xc5\u2e52\xd7h\xbb2\xe5Pr-\x94\xd5\xd4E$>\x00U\xdd\xf6\U000d93d5J\x1e\xfb\xf9/\xae\x98\xa8jkl\x856\x87\xf2\x1b\xaf\x1bW;\xe2\xb9\xd7\xf1\xda\xf5.\xed\b}\x90\x19\x19U\x95\\\ve5u\x11\x89\x0f4U\x19w\xaf\\\xbc\xf8\xed\xb7\xd7\xee\xb2o\xdf^\x89\xcc\x05\x14l\x8d\xad\x10\xb9\x03B4e\xb5{\x99G\xebɲ\x13\x1e6?\r\xcdU\x1f4\x1br-\x94\xd5\xd4E$>\x00U\xa5\xe2R\xc05?\xbd\xe2\x8c؊\x88h\xeaj\xc5[\xfdS\x8a\x9b\xf84`\xb1Ot\xd3H.\xa9\xb9\x16\xa8j\xd2\x00T\xb5\xbb\xb3\xf3Fg\xe7O'\xef\xed\xbcq\xbf\xd3\xfcB\x15;c+\"\xa2\xa9\xab=]\xa35\x93g\xf8\xec\xf7jN\x05;\x98\v\xfa\x87\x1br-Pդ\x01\xa8\xaa\xe4\xf6\x95\x1e.\xa9\xb6/\xb6\xe2B@\xab\xda\x17<\\\xa5\xf1dJ}5JWf\xe5\x04G\xfbV\xf0\x92\xe6\xacI\xbfk*\xcb\xe43\a=\xd7BY\xcd\xd0\x03\x12\x1f\x98\xaavR\xba\xf6\u007f\x9f\xa1\xf1\xffɊm\xb1\x15\xcf\xf0t\x8a\xd6l\xf6\xfd\x19e5J\x0f\xe5\xd6\xd2U\xd9\xfbE\xe9\xf1\xb2\xac\xfc\x8aV\xbe\xa4\xe7Z(\xab\x19{@\xe2\x02Sջ\x94\xb2\t\x00\x8d\xff\x0fU\xfb9\xb6\x02\xe9\x03`\xaaJ-&\x00\xfd\x1d[\x81\xf4\x010U\xc5\x1b\x01\xb9\x10\x98\xaa⍀\\\bLU)\xde\b\xc8}\xc0T\x15'\x00.\x04\xa6\xaa8\x01p!0U\xa58\x01p\x1f0U\xc5\t\x80\v\x81\xa9*N\x00\\\bLU)N\x00\xdc\a\xaa\x8a\x00\x01\xa6\xaa8Wu!0UŹ\xaa\v\x81\xa9*\xc5\t\x80\xfb\x00\xa6*\xc6V\xb8\x17`\xaabl\x85{\x01\xa6*\xc6V\xb8\x17`\xaabl\x85{\x81\xa6*\xc6V\xb8\x16\x80\xaabl\x85;\x01\xa8*\xc6V\xb8\x13\x88\xaabl\x85+\x01\xa9j_\xc7V`@\x85\x13\x01\xa8j\x8a\xb1\x15I\x90r@\x05҇\x00T5\xb5؊\xe4H-\xa0\x02\xe9K\x00\xaa\x9aZlE\x92\xa4\x12P\x81\xf4)\x10UM)\xb6\"IR\t\xa8@\xfa\x14\x88\xaa\xa6\x14[A\xe9\xe9Y\xf9Z\xc1\x8cohb\xe9\x111\x01\x15\x94\xee,+\xd2\xf2g\f\x13\xf7HM8\xf8\x02I\x17 UM%\xb6\x82\xb6d\x8f[\xb5\xa3\x8e\xf0{\xfd%\x92\x1e\x11\x13PA\x0fdT\xbe\xbdcc>\xe1\xb7XK<\xf8\x02I\x17\x10UM)\xb6\xa2\xa3\xa8\xec\x1e\x1bo\x1b\xaf&\x98\x1e\x11\x1bP\xb1.\x8fK\xba.7\x98l\xf0\x05\x92\x16\x00\xaa\x9aZlE39\x1c~:\xa1\xf4\x88\u0600\x8a\xf3\x85\xc3k6\x1e\x0e\xf2<\xa1\xe4\x82/\x90\xb4\x00MU\x9ajlE=\xd1'\x8e\t\xa5G\x98\x04T\\\xdf0\xbb\x98\xe4\xaf\n&\x1b|\x81\xa4\x05\x80\xaaҔb+vD\ue35ePzDl@š\xc5l\xb5\xeb[}\xeb\x92\r\xbe@\xd2\x02@US\x8b\xad\xb8U\xe0\xe7o\xdd5\xf3\x13K\x8f0\t\xa8\xa8\x13\x93[\xea\xafN6\xf8\x02I\v\x00U\x95$\x1b[A[\xbc\x0foh\xae!\x9biB\xe9\x11\xb1\x01\x15L\xd5\xec\xda\x0f\x9a\xe6\x12>\x17M<\xf8\x02I\x170UM!\xb6\x82ғ\xb3\x87\x0e\x9a(\xaeC\xb1N\x8f0\t\xa8\xa0\xafM\xab+\xd2\n\xfc-\xe2A\xc2\xc1\x17H\xba\x80\xa9j_\xc7V`@\x85\x03\x81\xa9*\xed\xdb\xd8\n\f\xa8p\"0U\xc5\x1b\x01\xb9\x10\x98\xaa⍀\\\bLU)\xde\b\xc8}\xc0T\x15'\x00.\x04\xa6\xaa8\x01p!0U\xa58\x01p\x1f0U\xc5\t\x80\v\x81\xa9*N\x00\\\bLU)N\x00\xdc\aXU\x11\xb7\x01SU6I\xfdxm\xfc\xebU\x91\x81\bLUq\xae\xeaB`\xaaJq\xae\xea>`\xaa\x8a'\xab\\\bLUq\x02\xe0B`\xaaJq\x02\xe0>`\xaa\x8a\x13\x00\x17\x02SU\x9c\x00\xb8\x10\x98\xaaR\x9c\x00\xb8\x0f\x98\xaa\xca\t@w'\xed\xbeϿpxu\x030U\rM\x00\x107\x01SUF獞\x87R\x8c\xad\x18h\xc0T\x95_\x03\xf0\xd6\xfd\xbd/u\xee];\xee\x1e\\\x1bS\xd1/\xb1\x15Gg\xe4\xe7Lk)\x89\xbd[\x06\x92\x06`\xaa\xca\xef\xb2\xfa\x93\xef^\x9fy[|\xdd\xe8\xdf؊\x96\xf0-\x83\x0ei\xe5MoT\x10y\xbb*\xbdռ\x16I\x1a\x98\xaa2\xee~G\xaf\xfd5\xf4u\xe3\\ԓ\xb6\xc6VLx2\xb4P\xe6g\x03\xe6\xac֍\x00\x00\aLIDATy\xb0J\xaa\xaa\xb7\x9a\xd7\"I\x03SUq\x06\xe0J\xfc\xe7m\x8d\xad\xd0\xef\x048|\t\xff~\x944\x19Z\xcdk\x91\xa4\x81\xa9\xaa8\x03\xf0U\xf7\xdd8'\xabl\x8c\xadh\n\xdd\xf3\x97\xdf\x0e\xf8\xc9\x02\xfeW\x11\xdc~\xcb\xd0zsv\xa1VT~\x84\x1ak1\xd7\"i`\xaaJ{\xfe\b\xc0\xc6؊;\xbb\xc5M+\x03'Xc{\x91\xa7\xacn\x0f\xbf\x8b\xab\xda\xfa.\xa9ni,\xf7\xec7\xb6b\xaeE\xd2\xc0T\xd5\xe2\x1a\x00\x9bc+\xf47\xf5\xab+&h$\xb7\x91\x1aZ;\x1ao\xb11\xb4\xa4\xc2؊\xb9\x16I\x03SU\x8bk\x00l\x8e\xadP\xe7\x9f\xf7v\x94\x89\xbba+\xad\x97ו\x8d\xc8!r\x9bz+\xe6Z$\rLUi\xcf\x13\x00\x9bc+\xc2\xfa\xed\xe7\xf3`\x1a\x94\xddGZ\v\x8a\x165\x05\xfcQ\xaab\xaeE\xd2\xc0T\xd5b\x02`sl\x05\xd7o\xf3ה\x16\x88\xc4\n\xbad\x94\xa1\xb5x\"\xff\x1b\x99\xa5\xa8\xca[1\xd7\"i`\xaaju\x11\xa0\xad\xb1\x15~?\xa5\x97xC~\xe1U\xbe\xa6L\\\xd1[\x8b\xf8\xc3\xe0X\xa9\xaaފ\xb9\x16I\x03SUjq\x11\xa0}\xb1\x15\xbc]\xabo\xf2g\xb3?\x88|RP\xdb\xdc\xe4\xf7\x9d4\xb4֑\xd9\xebV\x8cg\x13\x87}j+\xe6Z$\rLU-\xff\x15\x80m\xb1\x15\x8c{5\x83}\xd3\xf6\xb3\x85\t\x9b\x97\x14g\xe7U\x9c4\xb6\x06\xebGkyOn\x1e\xa5\xf9\xd5V̵H\x1a\x98\xaaZM\x000\xb6b\x00\x02SUj\xf9\xaf\x000\xb6b\xc0\x01SU\xcb\t\x002\xf0\x80\xa9\xaa\xe5\x04\x00\x19x\xc0T\x95ZN\x00\x90\x01\aLUq\x02\xe0B`\xaa\x8a\x13\x00\x17\x02SU\x8a\x13\x00\xf7\x01SU\x9c\x00\xb8\x10\x98\xaa\xe2\x04\xc0\x85\xc0T\x95\xe2\x04\xc0}\xa0\xaa\b\x10`\xaa\x8asU\x17\x02SU\x9c\xab\xba\x10\x98\xaaR\x9c\x00\xb8\x0f\x98\xaa\xe2\x04\xc0\x85\xc0T\x15'\x00.\x04\xa6\xaa\x14'\x00\xee\x03\xa6\xaa8\x01p!0U\xc5\t\x80\v\x81\xa9*\xc5\t\x80\xfb\x80\xa9*\xc6V\xb8\x10\x98\xaabl\x85\v\x81\xa9*\xed\xdb\xd8\n\x10\xb8.[\x03\xac\xaa\a\xdf\xeb>\xf8\xdbN\xf9\xf5_\xbf\x8fy:\xb1؊\xe6\f\xe2\xd9G?\xf1\x10\xdfu\xabRA\xbdW\u07b5\xa5\x8a\x10\x92u*ܺ#\xaf\ai\x8exXm\xe4~\u007f=\xd6&E\xdcl\x8d\xf0N\x0e4`\xaa\xca\x06\xd4_L\xbe\xb1\x96}=¾\xae\xbd\xfe\xf3\xe8\x02=\xb6\xa2眈\x8e\xb7Ɏ\a\xb4cԄ\x04\xd3$J4y멳\x81\xc0\xba\xf0\xdd\x06)\xfd ;\xfaV\xac\n]\x9f\x8c-\t\x9c\xd7\x1f\x9a֦\x18f\x11'[#\xbc\x93ɑ\xe2>\xd8\bLU\xad\x88\xc4VX\xe4D\xb4\x93[\x94\xd6\x0e\x89\xa8\xd4#w<\x95\x9e\xf0\xfd\x01\xf7GT\xa5=\x8f\xdf\xfc\x96j\x11\xccjS\r\xb30\xcd\xd6Pw2\tR\xdd\a\xfb\x18\x98\xaaFb+,r\"\xb8\xaa͙-=\xd6Dh!\x87H\xb8VU\xb5g\x8c\xaa\x9a\x91j\x98\x85i\xb6\x86\xba\x93I\x90\xea>\xd8ǀT5\x1c[aȉ\xd0c+\x9e!\x99\rՅ\x83\xcb\xf9\\\x93\xa9ڞ\xbbB\xae\xa5\x04I\xe8\x8bj-\xa5uCiamh\x1baU\xaf\xfb\b\xf1\x88ۤ7\xb2-\xd5\xd1:\"\x82\xab\x94\xce\"\xaaFj\x95\f\f\xf30\vC\x8a\x86\xdez$\x93\x90\xa5\xa7*\x87\xfb\xca\xe4-\xb5L\xb25ԝ\x8c\x04u\xa8\x99\x1d&\xaf\xcd\xf8\x1fʡ\fHUñ\x15\x86\x9c\b=\xb6\x82\aT\f[\xb1bX\xd61\xaeꥒA\xf7\xe4ZJ\x90\x84\xbe\xa8\xd62\xe9f\xd1\xd9a\xef\xf4Q\xf5P \xe0\x15w\x1e\xbe\xb53g\xd9%z\xa96w\xe7-Cgʨ\xaa\xd7*\x19\x18\xe6a\x16\x86\x14\r\xbd\xb5\xa3q\xeb\xb0у\x8a\x16Tf|-z\x89\xcd\xd6PwR\t\xeaP\x16\xcd^\x9ba\x1f\x9cʀTU\x89\xad\x88\xa4GDb+\xa86\xfc&\x1b\xe2\x8a&rU\x9f\x1eU\xb0N\x14(A\x12j\xa6D\xa4\x96\x06\xb3\xebi}vh\xb2\xa9N\x00|\xa1\x9bd\xcf\xe3\xf3\xbdʟ\x19;\x8b\x9a\x00\x84j\x95\f\x8c8a\x16\x91\x14\rcH\x06\xf1ߤ\xc1\x9b\xb2>6[C\xd9I\xe5\x15+\x8bq^\x1bN\x00\xfa\a=\xb6B\xf9\r(\xb1\x15T\x1et\xad#W\x99\xaa\xbe㛇\x88_\xbc\x12$\xa1fJDj\xe9\x11\xb2\xbbc79\"\xfb0S\xb5\x85\xbd\x1fwd\xb5\x18;3WU\xc9\xc0\x88\x13f\x11I\xd10\x86dh_G:\x8b\xcd\xd6PvRy\xc5\xcab\x9c׆\xaa\xf6\x0f\xfb\"\x1a\xe9\xbf\x01%\xb6B\xdeJ\x9d\x06\xc8!\xa6\xeaV\xdaU,R\xfc\x94 \t5S\"RK\x1bDc\xe8\x04\x91\x99\xaa]\xf9M\xb4)?h\xec\xcc\\U%\x03#N\x98E\xe4~\xefƐ\fu>i\x92\xad\x11\xd9I\xe5\x15+\x8bq^\x1b\xaa\xda?Db+\"9\x11Jl\x05\xd5\xe6\xf3\xef\x1b\xc9My\xb2\xaa\xd9\xcbOV)A\x12j\xa6D\xa4\x96\xce\x1a\xb7\u007f\xff\xfeq\xb3d\x1ff\xaaҚ\nZ!\xb2+\xd4\x1e\xa4\xaa\xb7\x96]Uk\x95\f\x8c8a\x16\x11U\x8d!\x19\xb3h\x84\xd8l\re'\x95W\xac,\xc6ym\x91}p,\x03RU%\xb6BωPb+\xa8\x96\xcf~\xc3wF\xf8C\xe7U\x83\x93x\x82\x95\x12$\xa1fJDji\xe1B\xf6mA\xa1\xec\xd8T\xd5=\xde\v^q\xa0\xa3\xf6 U=Lv\xaa\xb5J\x06F\x9c0\x8b\x88\xaa\x86\x88\vu\xf43\xc9\xd6PvRy\xc5\xcab\x9c\xd7\x16\xd9\a\xc720U\x8d\xc4VDr\"\x94\xd8\n\x8d\x8ck\xdc<:\xf7$\xedh\xe2\x9fVѷ3\xb6\xdf3\x04I(\x8b\x91\xdaf\xb2\xe4\x0e\xbd\xf3+\xd2|\x8f\x9e\xe7\x9fV\xd5\a\x02l\x10z\xf0\t;\xaa\xaf\n\xec\x14\xf3\xdd`aY\xa1\xfc#\xd1{\xe8\xda3\xb6\x84\x1d[\a6\x90\x80Z\xabf`\x98\x85Y\x18R4\x94\xceđzx&\x1e\x9b\xad\xa1\xee\xa4\xfa\x8a\x95E\xb3\xd7f\xd8\a\xa720U\x8d\xc4V(9\x11\x91\xd8\nm\xe1ܜ\xc2\xca\v|\x88\xe1\xd7\x00\xd0i$\x83\x0f\x91J\x90DdQ\xafݑ\xc1O\x986\x11\x92\xb1\x83\xce\tM\xf8\xd8\x11\xff\x01\x8f\\\x94\xd1\x16\xf5Z}h\x0f\xc2=\x1c\r=O|'\xd4ZC\x06\x86I\x98\x851E#\xdczDv\x10\x1aKM\xb25ԝT_\xb1\xbah\xf2ڌ\xfb\xe0P\x06\xa8\xaa=\xc7VD\xa6\xb2\xd6$Sk/\xbd\xcf\xd6p\xeek3c\x80\xaa\xdaslE2\xbf\xa2djm%\r\xd9\x1a\x8e}m\xa6\fTU{$\x99_Q2\xb5Ѐ\xf5\xda\\\xa8\xea7\xe2\x88ŪJ\x92L-4\xa0\xbd6\x17\xaa*\x8eX\xdaiB$S\v\rh\xafͅ\xaa\"0AU\x11 \xa0\xaa\b\x10PU\x04\b\xa8*\x02\x04T\x15\x01\x02\xaa\x8a\x00\x01UE\x80\x80\xaa\"@@U\x11 \xa0\xaa\b\x10PU\x04\b\xa8*\x02\x04T\x15\x01\x02\xaa\x8a\x00\x01UE\x80\x80\xaa\"@@U\x11 \xa0\xaa\b\x10PU\x04\b\xa8*\x02\x04T\x15\x01\xc2\xff\amu\xa3\x1c\xa2\xebff\x00\x00\x00\x00IEND\xaeB`\x82", @@ -478,7 +478,16 @@ var Files = map[string]string{ <link rel="search" type="application/opensearchdescription+xml" title="godoc" href="/opensearch.xml" /> {{end}} <link rel="stylesheet" href="/lib/godoc/jquery.treeview.css"> -<script type="text/javascript">window.initFuncs = [];</script> +<script>window.initFuncs = [];</script> +<script src="/lib/godoc/jquery.js" defer></script> +<script src="/lib/godoc/jquery.treeview.js" defer></script> +<script src="/lib/godoc/jquery.treeview.edit.js" defer></script> + +{{if .Playground}} +<script src="/lib/godoc/playground.js" defer></script> +{{end}} +{{with .Version}}<script>var goVersion = {{printf "%q" .}};</script>{{end}} +<script src="/lib/godoc/godocs.js" defer></script> </head> <body> @@ -567,18 +576,6 @@ and code is licensed under a <a href="/LICENSE">BSD license</a>.<br> </div><!-- .container --> </div><!-- #page --> - -<!-- TODO(adonovan): load these from <head> using "defer" attribute? --> -<script type="text/javascript" src="/lib/godoc/jquery.js"></script> -<script type="text/javascript" src="/lib/godoc/jquery.treeview.js"></script> -<script type="text/javascript" src="/lib/godoc/jquery.treeview.edit.js"></script> - -{{if .Playground}} -<script type="text/javascript" src="/lib/godoc/playground.js"></script> -{{end}} -{{with .Version}}<script>var goVersion = {{printf "%q" .}};</script>{{end}} -<script type="text/javascript" src="/lib/godoc/godocs.js"></script> - </body> </html> @@ -1666,9 +1663,9 @@ function cgAddChild(tree, ul, cgn) { <div class="expanded"> <h2 class="toggleButton" title="Click to hide Overview section">Overview ▾</h2> {{comment_html .Doc}} + {{example_html $ ""}} </div> </div> - {{example_html $ ""}} <div id="pkg-index" class="toggleVisible"> <div class="collapsed"> @@ -1942,6 +1939,7 @@ function cgAddChild(tree, ul, cgn) { <li><a href="//godoc.org/golang.org/x/net">net</a> — additional networking packages.</li> <li><a href="//godoc.org/golang.org/x/sys">sys</a> — packages for making system calls.</li> <li><a href="//godoc.org/golang.org/x/text">text</a> — packages for working with text.</li> + <li><a href="//godoc.org/golang.org/x/time">time</a> — additional time packages.</li> <li><a href="//godoc.org/golang.org/x/tools">tools</a> — godoc, goimports, gorename, and other tools.</li> <li><a href="//godoc.org/golang.org/x/tour">tour</a> — <a href="//tour.golang.org">tour.golang.org</a>'s implementation.</li> <li><a href="//godoc.org/golang.org/x/exp">exp</a> — experimental and deprecated packages (handle with care; may change without warning).</li> diff --git a/vendor/golang.org/x/tools/imports/fix.go b/vendor/golang.org/x/tools/imports/fix.go index d792a78c7..68961ba65 100644 --- a/vendor/golang.org/x/tools/imports/fix.go +++ b/vendor/golang.org/x/tools/imports/fix.go @@ -49,7 +49,7 @@ func localPrefixes() []string { var importToGroup = []func(importPath string) (num int, ok bool){ func(importPath string) (num int, ok bool) { for _, p := range localPrefixes() { - if strings.HasPrefix(importPath, p) { + if strings.HasPrefix(importPath, p) || strings.TrimSuffix(p, "/") == importPath { return 3, true } } diff --git a/vendor/golang.org/x/tools/imports/fix_test.go b/vendor/golang.org/x/tools/imports/fix_test.go index b8d51a364..10e397d4b 100644 --- a/vendor/golang.org/x/tools/imports/fix_test.go +++ b/vendor/golang.org/x/tools/imports/fix_test.go @@ -1444,6 +1444,29 @@ import ( const Y = bar.X const _ = runtime.GOOS +`, + }, + { + config: testConfig{ + gopathFiles: map[string]string{ + "foo/foo.go": "package foo \n const X = 1", + "foo/bar/bar.go": "package bar \n const X = 1", + }, + }, + localPrefix: "foo/", + src: "package main \n const Y = bar.X \n const Z = foo.X \n const _ = runtime.GOOS", + want: `package main + +import ( + "runtime" + + "foo" + "foo/bar" +) + +const Y = bar.X +const Z = foo.X +const _ = runtime.GOOS `, }, { @@ -2090,8 +2113,7 @@ const x = mypkg.Sprintf("%s", "my package") // end ` - if got := string(out); got != want { - t.Errorf("Process returned unexpected result.\ngot:\n%v\nwant:\n%v", got, want) + t.Errorf("Process returned unexpected result.\ngot:\n%.100v\nwant:\n%.100v", got, want) } } diff --git a/vendor/golang.org/x/tools/refactor/eg/eg.go b/vendor/golang.org/x/tools/refactor/eg/eg.go index bf0ee2909..02c6dc951 100644 --- a/vendor/golang.org/x/tools/refactor/eg/eg.go +++ b/vendor/golang.org/x/tools/refactor/eg/eg.go @@ -145,6 +145,7 @@ type Transformer struct { env map[string]ast.Expr // maps parameter name to wildcard binding importedObjs map[types.Object]*ast.SelectorExpr // objects imported by after(). before, after ast.Expr + afterStmts []ast.Stmt allowWildcards bool // Working state of Transform(): @@ -198,7 +199,7 @@ func NewTransformer(fset *token.FileSet, tmplPkg *types.Package, tmplFile *ast.F if err != nil { return nil, fmt.Errorf("before: %s", err) } - after, err := soleExpr(afterDecl) + afterStmts, after, err := stmtAndExpr(afterDecl) if err != nil { return nil, fmt.Errorf("after: %s", err) } @@ -242,6 +243,7 @@ func NewTransformer(fset *token.FileSet, tmplPkg *types.Package, tmplFile *ast.F importedObjs: make(map[types.Object]*ast.SelectorExpr), before: before, after: after, + afterStmts: afterStmts, } // Combine type info from the template and input packages, and @@ -279,6 +281,7 @@ func WriteAST(fset *token.FileSet, filename string, f *ast.File) (err error) { if err != nil { return err } + defer func() { if err2 := fh.Close(); err != nil { err = err2 // prefer earlier error @@ -319,6 +322,33 @@ func soleExpr(fn *ast.FuncDecl) (ast.Expr, error) { return nil, fmt.Errorf("must contain a single return or expression statement") } +// stmtAndExpr returns the expression in the last return statement as well as the preceeding lines. +func stmtAndExpr(fn *ast.FuncDecl) ([]ast.Stmt, ast.Expr, error) { + if fn.Body == nil { + return nil, nil, fmt.Errorf("no body") + } + + n := len(fn.Body.List) + if n == 0 { + return nil, nil, fmt.Errorf("must contain at least one statement") + } + + stmts, last := fn.Body.List[:n-1], fn.Body.List[n-1] + + switch last := last.(type) { + case *ast.ReturnStmt: + if len(last.Results) != 1 { + return nil, nil, fmt.Errorf("return statement must have a single operand") + } + return stmts, last.Results[0], nil + + case *ast.ExprStmt: + return stmts, last.X, nil + } + + return nil, nil, fmt.Errorf("must end with a single return or expression statement") +} + // mergeTypeInfo adds type info from src to dst. func mergeTypeInfo(dst, src *types.Info) { for k, v := range src.Types { diff --git a/vendor/golang.org/x/tools/refactor/eg/eg_test.go b/vendor/golang.org/x/tools/refactor/eg/eg_test.go index 896bc9b08..89b7d08fb 100644 --- a/vendor/golang.org/x/tools/refactor/eg/eg_test.go +++ b/vendor/golang.org/x/tools/refactor/eg/eg_test.go @@ -78,6 +78,12 @@ func Test(t *testing.T) { "testdata/H.template", "testdata/H1.go", + "testdata/I.template", + "testdata/I1.go", + + "testdata/J.template", + "testdata/J1.go", + "testdata/bad_type.template", "testdata/no_before.template", "testdata/no_after_return.template", diff --git a/vendor/golang.org/x/tools/refactor/eg/rewrite.go b/vendor/golang.org/x/tools/refactor/eg/rewrite.go index dd28aa578..a1281582b 100644 --- a/vendor/golang.org/x/tools/refactor/eg/rewrite.go +++ b/vendor/golang.org/x/tools/refactor/eg/rewrite.go @@ -22,6 +22,52 @@ import ( "golang.org/x/tools/go/ast/astutil" ) +// transformItem takes a reflect.Value representing a variable of type ast.Node +// transforms its child elements recursively with apply, and then transforms the +// actual element if it contains an expression. +func (tr *Transformer) transformItem(rv reflect.Value) (reflect.Value, bool, map[string]ast.Expr) { + // don't bother if val is invalid to start with + if !rv.IsValid() { + return reflect.Value{}, false, nil + } + + rv, changed, newEnv := tr.apply(tr.transformItem, rv) + + e := rvToExpr(rv) + if e == nil { + return rv, changed, newEnv + } + + savedEnv := tr.env + tr.env = make(map[string]ast.Expr) // inefficient! Use a slice of k/v pairs + + if tr.matchExpr(tr.before, e) { + if tr.verbose { + fmt.Fprintf(os.Stderr, "%s matches %s", + astString(tr.fset, tr.before), astString(tr.fset, e)) + if len(tr.env) > 0 { + fmt.Fprintf(os.Stderr, " with:") + for name, ast := range tr.env { + fmt.Fprintf(os.Stderr, " %s->%s", + name, astString(tr.fset, ast)) + } + } + fmt.Fprintf(os.Stderr, "\n") + } + tr.nsubsts++ + + // Clone the replacement tree, performing parameter substitution. + // We update all positions to n.Pos() to aid comment placement. + rv = tr.subst(tr.env, reflect.ValueOf(tr.after), + reflect.ValueOf(e.Pos())) + changed = true + newEnv = tr.env + } + tr.env = savedEnv + + return rv, changed, newEnv +} + // Transform applies the transformation to the specified parsed file, // whose type information is supplied in info, and returns the number // of replacements that were made. @@ -43,48 +89,14 @@ func (tr *Transformer) Transform(info *types.Info, pkg *types.Package, file *ast if tr.verbose { fmt.Fprintf(os.Stderr, "before: %s\n", astString(tr.fset, tr.before)) fmt.Fprintf(os.Stderr, "after: %s\n", astString(tr.fset, tr.after)) + fmt.Fprintf(os.Stderr, "afterStmts: %s\n", tr.afterStmts) } - var f func(rv reflect.Value) reflect.Value - f = func(rv reflect.Value) reflect.Value { - // don't bother if val is invalid to start with - if !rv.IsValid() { - return reflect.Value{} - } - - rv = apply(f, rv) - - e := rvToExpr(rv) - if e != nil { - savedEnv := tr.env - tr.env = make(map[string]ast.Expr) // inefficient! Use a slice of k/v pairs - - if tr.matchExpr(tr.before, e) { - if tr.verbose { - fmt.Fprintf(os.Stderr, "%s matches %s", - astString(tr.fset, tr.before), astString(tr.fset, e)) - if len(tr.env) > 0 { - fmt.Fprintf(os.Stderr, " with:") - for name, ast := range tr.env { - fmt.Fprintf(os.Stderr, " %s->%s", - name, astString(tr.fset, ast)) - } - } - fmt.Fprintf(os.Stderr, "\n") - } - tr.nsubsts++ - - // Clone the replacement tree, performing parameter substitution. - // We update all positions to n.Pos() to aid comment placement. - rv = tr.subst(tr.env, reflect.ValueOf(tr.after), - reflect.ValueOf(e.Pos())) - } - tr.env = savedEnv - } - - return rv + o, changed, _ := tr.apply(tr.transformItem, reflect.ValueOf(file)) + if changed { + panic("BUG") } - file2 := apply(f, reflect.ValueOf(file)).Interface().(*ast.File) + file2 := o.Interface().(*ast.File) // By construction, the root node is unchanged. if file != file2 { @@ -150,45 +162,91 @@ var ( identType = reflect.TypeOf((*ast.Ident)(nil)) selectorExprType = reflect.TypeOf((*ast.SelectorExpr)(nil)) objectPtrType = reflect.TypeOf((*ast.Object)(nil)) + statementType = reflect.TypeOf((*ast.Stmt)(nil)).Elem() positionType = reflect.TypeOf(token.NoPos) scopePtrType = reflect.TypeOf((*ast.Scope)(nil)) ) // apply replaces each AST field x in val with f(x), returning val. // To avoid extra conversions, f operates on the reflect.Value form. -func apply(f func(reflect.Value) reflect.Value, val reflect.Value) reflect.Value { +// f takes a reflect.Value representing the variable to modify of type ast.Node. +// It returns a reflect.Value containing the transformed value of type ast.Node, +// whether any change was made, and a map of identifiers to ast.Expr (so we can +// do contextually correct substitutions in the parent statements). +func (tr *Transformer) apply(f func(reflect.Value) (reflect.Value, bool, map[string]ast.Expr), val reflect.Value) (reflect.Value, bool, map[string]ast.Expr) { if !val.IsValid() { - return reflect.Value{} + return reflect.Value{}, false, nil } // *ast.Objects introduce cycles and are likely incorrect after // rewrite; don't follow them but replace with nil instead if val.Type() == objectPtrType { - return objectPtrNil + return objectPtrNil, false, nil } // similarly for scopes: they are likely incorrect after a rewrite; // replace them with nil if val.Type() == scopePtrType { - return scopePtrNil + return scopePtrNil, false, nil } switch v := reflect.Indirect(val); v.Kind() { case reflect.Slice: + // no possible rewriting of statements. + if v.Type().Elem() != statementType { + changed := false + var envp map[string]ast.Expr + for i := 0; i < v.Len(); i++ { + e := v.Index(i) + o, localchanged, env := f(e) + if localchanged { + changed = true + // we clobber envp here, + // which means if we have two sucessive + // replacements inside the same statement + // we will only generate the setup for one of them. + envp = env + } + setValue(e, o) + } + return val, changed, envp + } + + // statements are rewritten. + var out []ast.Stmt for i := 0; i < v.Len(); i++ { e := v.Index(i) - setValue(e, f(e)) + o, changed, env := f(e) + if changed { + for _, s := range tr.afterStmts { + t := tr.subst(env, reflect.ValueOf(s), reflect.Value{}).Interface() + out = append(out, t.(ast.Stmt)) + } + } + setValue(e, o) + out = append(out, e.Interface().(ast.Stmt)) } + return reflect.ValueOf(out), false, nil case reflect.Struct: + changed := false + var envp map[string]ast.Expr for i := 0; i < v.NumField(); i++ { e := v.Field(i) - setValue(e, f(e)) + o, localchanged, env := f(e) + if localchanged { + changed = true + envp = env + } + setValue(e, o) } + return val, changed, envp case reflect.Interface: e := v.Elem() - setValue(v, f(e)) + o, changed, env := f(e) + setValue(v, o) + return val, changed, env } - return val + return val, false, nil } // subst returns a copy of (replacement) pattern with values from env diff --git a/vendor/golang.org/x/tools/refactor/eg/testdata/I.template b/vendor/golang.org/x/tools/refactor/eg/testdata/I.template new file mode 100644 index 000000000..d03e77482 --- /dev/null +++ b/vendor/golang.org/x/tools/refactor/eg/testdata/I.template @@ -0,0 +1,14 @@ +// +build ignore + +package templates + +import ( + "errors" + "fmt" +) + +func before(s string) error { return fmt.Errorf("%s", s) } +func after(s string) error { + n := fmt.Sprintf("error - %s", s) + return errors.New(n) +} diff --git a/vendor/golang.org/x/tools/refactor/eg/testdata/I1.go b/vendor/golang.org/x/tools/refactor/eg/testdata/I1.go new file mode 100644 index 000000000..d1762ebb3 --- /dev/null +++ b/vendor/golang.org/x/tools/refactor/eg/testdata/I1.go @@ -0,0 +1,9 @@ +// +build ignore + +package I1 + +import "fmt" + +func example() { + _ = fmt.Errorf("%s", "foo") +} diff --git a/vendor/golang.org/x/tools/refactor/eg/testdata/I1.golden b/vendor/golang.org/x/tools/refactor/eg/testdata/I1.golden new file mode 100644 index 000000000..f33b3e106 --- /dev/null +++ b/vendor/golang.org/x/tools/refactor/eg/testdata/I1.golden @@ -0,0 +1,14 @@ +// +build ignore + +package I1 + +import ( + "errors" + "fmt" +) + +func example() { + + n := fmt.Sprintf("error - %s", "foo") + _ = errors.New(n) +} diff --git a/vendor/golang.org/x/tools/refactor/eg/testdata/J.template b/vendor/golang.org/x/tools/refactor/eg/testdata/J.template new file mode 100644 index 000000000..6f82cdfe8 --- /dev/null +++ b/vendor/golang.org/x/tools/refactor/eg/testdata/J.template @@ -0,0 +1,11 @@ +// +build ignore + +package templates + +import () + +func before(x int) int { return x + x + x } +func after(x int) int { + temp := x + x + return temp + x +} diff --git a/vendor/golang.org/x/tools/refactor/eg/testdata/J1.go b/vendor/golang.org/x/tools/refactor/eg/testdata/J1.go new file mode 100644 index 000000000..2fbeee801 --- /dev/null +++ b/vendor/golang.org/x/tools/refactor/eg/testdata/J1.go @@ -0,0 +1,10 @@ +// +build ignore + +package I1 + +import "fmt" + +func example() { + temp := 5 + fmt.Print(temp + temp + temp) +} diff --git a/vendor/golang.org/x/tools/refactor/eg/testdata/J1.golden b/vendor/golang.org/x/tools/refactor/eg/testdata/J1.golden new file mode 100644 index 000000000..bb2f11c60 --- /dev/null +++ b/vendor/golang.org/x/tools/refactor/eg/testdata/J1.golden @@ -0,0 +1,11 @@ +// +build ignore + +package I1 + +import "fmt" + +func example() { + temp := 5 + temp := temp + temp + fmt.Print(temp + temp) +} diff --git a/vendor/golang.org/x/tools/refactor/eg/testdata/no_after_return.template b/vendor/golang.org/x/tools/refactor/eg/testdata/no_after_return.template index 536b01e67..dd2cbf61e 100644 --- a/vendor/golang.org/x/tools/refactor/eg/testdata/no_after_return.template +++ b/vendor/golang.org/x/tools/refactor/eg/testdata/no_after_return.template @@ -1,6 +1,4 @@ package template -const shouldFail = "after: must contain a single statement" - func before() int { return 0 } func after() int { println(); return 0 } diff --git a/vendor/k8s.io/apiextensions-apiserver/.github/PULL_REQUEST_TEMPLATE.md b/vendor/k8s.io/apiextensions-apiserver/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index e559c074b..000000000 --- a/vendor/k8s.io/apiextensions-apiserver/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,2 +0,0 @@ -Sorry, we do not accept changes directly against this repository. Please see -CONTRIBUTING.md for information on where and how to contribute instead. diff --git a/vendor/k8s.io/apiextensions-apiserver/BUILD b/vendor/k8s.io/apiextensions-apiserver/BUILD index 8092fcb82..ad62604f3 100644 --- a/vendor/k8s.io/apiextensions-apiserver/BUILD +++ b/vendor/k8s.io/apiextensions-apiserver/BUILD @@ -8,7 +8,8 @@ load( go_binary( name = "apiextensions-apiserver", - embed = [":go_default_library"], + importpath = "k8s.io/apiextensions-apiserver", + library = ":go_default_library", ) go_library( diff --git a/vendor/k8s.io/apiextensions-apiserver/CONTRIBUTING.md b/vendor/k8s.io/apiextensions-apiserver/CONTRIBUTING.md deleted file mode 100644 index d8ad4d2d3..000000000 --- a/vendor/k8s.io/apiextensions-apiserver/CONTRIBUTING.md +++ /dev/null @@ -1,7 +0,0 @@ -# Contributing guidelines - -Do not open pull requests directly against this repository, they will be ignored. Instead, please open pull requests against [kubernetes/kubernetes](https://git.k8s.io/kubernetes/). Please follow the same [contributing guide](https://git.k8s.io/kubernetes/CONTRIBUTING.md) you would follow for any other pull request made to kubernetes/kubernetes. - -This repository is published from [kubernetes/kubernetes/staging/src/k8s.io/apiextensions-apiserver](https://git.k8s.io/kubernetes/staging/src/k8s.io/apiextensions-apiserver) by the [kubernetes publishing-bot](https://git.k8s.io/publishing-bot). - -Please see [Staging Directory and Publishing](https://git.k8s.io/community/contributors/devel/staging.md) for more information diff --git a/vendor/k8s.io/apiextensions-apiserver/Godeps/Godeps.json b/vendor/k8s.io/apiextensions-apiserver/Godeps/Godeps.json index 5eb2a5481..6f4cd59a5 100644 --- a/vendor/k8s.io/apiextensions-apiserver/Godeps/Godeps.json +++ b/vendor/k8s.io/apiextensions-apiserver/Godeps/Godeps.json @@ -30,309 +30,49 @@ "ImportPath": "github.com/beorn7/perks/quantile", "Rev": "3ac7bf7a47d159a033b107610db8a1b6575507a4" }, - { - "ImportPath": "github.com/cockroachdb/cmux", - "Rev": "112f0506e7743d64a6eb8fedbcff13d9979bbf92" - }, - { - "ImportPath": "github.com/coreos/bbolt", - "Rev": "48ea1b39c25fc1bab3506fbc712ecbaa842c4d2d" - }, - { - "ImportPath": "github.com/coreos/etcd/alarm", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/auth", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, { "ImportPath": "github.com/coreos/etcd/auth/authpb", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" + "Rev": "0520cb9304cb2385f7e72b8bc02d6e4d3257158a" }, { "ImportPath": "github.com/coreos/etcd/client", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" + "Rev": "0520cb9304cb2385f7e72b8bc02d6e4d3257158a" }, { "ImportPath": "github.com/coreos/etcd/clientv3", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/clientv3/concurrency", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/clientv3/namespace", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/clientv3/naming", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/compactor", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/discovery", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/embed", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/error", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/etcdserver", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/etcdserver/api", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/etcdserver/api/etcdhttp", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/etcdserver/api/v2http", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/etcdserver/api/v2http/httptypes", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3client", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3election", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3election/v3electionpb/gw", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3lock", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3lock/v3lockpb/gw", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" + "Rev": "0520cb9304cb2385f7e72b8bc02d6e4d3257158a" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/etcdserver/auth", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" + "Rev": "0520cb9304cb2385f7e72b8bc02d6e4d3257158a" }, { "ImportPath": "github.com/coreos/etcd/etcdserver/etcdserverpb", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/etcdserver/etcdserverpb/gw", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/etcdserver/membership", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/etcdserver/stats", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/integration", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/lease", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/lease/leasehttp", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/lease/leasepb", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/mvcc", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/mvcc/backend", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" + "Rev": "0520cb9304cb2385f7e72b8bc02d6e4d3257158a" }, { "ImportPath": "github.com/coreos/etcd/mvcc/mvccpb", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/pkg/adt", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/pkg/contention", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/pkg/cors", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/pkg/cpuutil", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/pkg/crc", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/pkg/debugutil", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" + "Rev": "0520cb9304cb2385f7e72b8bc02d6e4d3257158a" }, { "ImportPath": "github.com/coreos/etcd/pkg/fileutil", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/pkg/httputil", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/pkg/idutil", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/pkg/ioutil", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/pkg/logutil", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/pkg/monotime", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/pkg/netutil", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" + "Rev": "0520cb9304cb2385f7e72b8bc02d6e4d3257158a" }, { "ImportPath": "github.com/coreos/etcd/pkg/pathutil", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/pkg/pbutil", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/pkg/runtime", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/pkg/schedule", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/pkg/srv", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/pkg/testutil", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" + "Rev": "0520cb9304cb2385f7e72b8bc02d6e4d3257158a" }, { "ImportPath": "github.com/coreos/etcd/pkg/tlsutil", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" + "Rev": "0520cb9304cb2385f7e72b8bc02d6e4d3257158a" }, { "ImportPath": "github.com/coreos/etcd/pkg/transport", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" + "Rev": "0520cb9304cb2385f7e72b8bc02d6e4d3257158a" }, { "ImportPath": "github.com/coreos/etcd/pkg/types", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/pkg/wait", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/proxy/grpcproxy", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/proxy/grpcproxy/adapter", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/proxy/grpcproxy/cache", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/raft", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/raft/raftpb", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/rafthttp", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/snap", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/snap/snappb", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/store", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/version", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/wal", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/etcd/wal/walpb", - "Rev": "95a726a27e09030f9ccbd9982a1508f5a6d25ada" - }, - { - "ImportPath": "github.com/coreos/go-semver/semver", - "Rev": "568e959cd89871e61434c1143528d9162da89ef2" + "Rev": "0520cb9304cb2385f7e72b8bc02d6e4d3257158a" }, { "ImportPath": "github.com/coreos/go-systemd/daemon", @@ -350,10 +90,6 @@ "ImportPath": "github.com/davecgh/go-spew/spew", "Rev": "782f4967f2dc4564575ca782fe2d04090b5faca8" }, - { - "ImportPath": "github.com/dgrijalva/jwt-go", - "Rev": "01aeca54ebda6e0fbfafd0a524d234159c05ec20" - }, { "ImportPath": "github.com/elazarl/go-bindata-assetfs", "Rev": "3dcc96556217539f50599357fb481ac0dc7439b9" @@ -404,7 +140,7 @@ }, { "ImportPath": "github.com/go-openapi/spec", - "Rev": "1de3e0542de65ad8d75452a595886fdd0befb363" + "Rev": "7abd5745472fff5eb3685386d5fb8bf38683154d" }, { "ImportPath": "github.com/go-openapi/strfmt", @@ -416,7 +152,7 @@ }, { "ImportPath": "github.com/go-openapi/validate", - "Rev": "d509235108fcf6ab4913d2dcb3a2260c0db2108e" + "Rev": "deaf2c9013bc1a7f4c774662259a506ba874d80f" }, { "ImportPath": "github.com/gogo/protobuf/proto", @@ -430,10 +166,6 @@ "ImportPath": "github.com/golang/glog", "Rev": "44145f04b68cf362d9c4df2182967c2275eaefed" }, - { - "ImportPath": "github.com/golang/groupcache/lru", - "Rev": "02826c3e79038b59d737d3b1c0a1d937f71a4433" - }, { "ImportPath": "github.com/golang/protobuf/jsonpb", "Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9" @@ -442,10 +174,6 @@ "ImportPath": "github.com/golang/protobuf/proto", "Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9" }, - { - "ImportPath": "github.com/golang/protobuf/protoc-gen-go/descriptor", - "Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9" - }, { "ImportPath": "github.com/golang/protobuf/ptypes", "Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9" @@ -486,21 +214,29 @@ "ImportPath": "github.com/googleapis/gnostic/extensions", "Rev": "0c5108395e2debce0d731cf0287ddf7242066aba" }, + { + "ImportPath": "github.com/gregjones/httpcache", + "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" + }, + { + "ImportPath": "github.com/gregjones/httpcache/diskcache", + "Rev": "787624de3eb7bd915c329cba748687a3b22666a6" + }, { "ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus", "Rev": "2500245aa6110c562d17020fb31a2c133d737799" }, { "ImportPath": "github.com/grpc-ecosystem/grpc-gateway/runtime", - "Rev": "8cc3a55af3bcf171a1c23a90c4df9cf591706104" + "Rev": "84398b94e188ee336f307779b57b3aa91af7063c" }, { "ImportPath": "github.com/grpc-ecosystem/grpc-gateway/runtime/internal", - "Rev": "8cc3a55af3bcf171a1c23a90c4df9cf591706104" + "Rev": "84398b94e188ee336f307779b57b3aa91af7063c" }, { "ImportPath": "github.com/grpc-ecosystem/grpc-gateway/utilities", - "Rev": "8cc3a55af3bcf171a1c23a90c4df9cf591706104" + "Rev": "84398b94e188ee336f307779b57b3aa91af7063c" }, { "ImportPath": "github.com/hashicorp/golang-lru", @@ -523,12 +259,12 @@ "Rev": "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" }, { - "ImportPath": "github.com/jonboulle/clockwork", - "Rev": "72f9bd7c4e0c2a40055ab3d0f09654f730cce982" + "ImportPath": "github.com/json-iterator/go", + "Rev": "36b14963da70d11297d313183d7e6388c8510e1e" }, { - "ImportPath": "github.com/json-iterator/go", - "Rev": "13f86432b882000a51c6e610c620974462691a97" + "ImportPath": "github.com/juju/ratelimit", + "Rev": "5b9ff866471762aa2ab2dced63c9fb6f53921342" }, { "ImportPath": "github.com/mailru/easyjson/buffer", @@ -546,10 +282,18 @@ "ImportPath": "github.com/matttproud/golang_protobuf_extensions/pbutil", "Rev": "fc2b8d3a73c4867e51861bbdd5ae3c1f0869dd6a" }, + { + "ImportPath": "github.com/mxk/go-flowrate/flowrate", + "Rev": "cca7078d478f8520f85629ad7c68962d31ed7682" + }, { "ImportPath": "github.com/pborman/uuid", "Rev": "ca53cad383cad2479bbba7f7a1a05797ec1386e4" }, + { + "ImportPath": "github.com/peterbourgon/diskv", + "Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6" + }, { "ImportPath": "github.com/pmezard/go-difflib/difflib", "Rev": "d8ed2627bdf02c080bf22230dbb337003b7aba2d" @@ -584,11 +328,11 @@ }, { "ImportPath": "github.com/spf13/cobra", - "Rev": "6644d46b81fa1831979c4cded0106e774e0ef0ab" + "Rev": "f62e98d28ab7ad31d707ba837a966378465c7b57" }, { "ImportPath": "github.com/spf13/pflag", - "Rev": "4c012f6dcd9546820e378d0bdda4d8fc772cdfea" + "Rev": "9ff6c6923cfffbcd502984b8e0c80539a94968b7" }, { "ImportPath": "github.com/stretchr/testify/assert", @@ -602,18 +346,6 @@ "ImportPath": "github.com/ugorji/go/codec", "Rev": "ded73eae5db7e7a0ef6f55aace87a2873c5d2b74" }, - { - "ImportPath": "github.com/xiang90/probing", - "Rev": "07dd2e8dfe18522e9c447ba95f2fe95262f63bb2" - }, - { - "ImportPath": "golang.org/x/crypto/bcrypt", - "Rev": "81e90905daefcd6fd217b62423c0908922eadb30" - }, - { - "ImportPath": "golang.org/x/crypto/blowfish", - "Rev": "81e90905daefcd6fd217b62423c0908922eadb30" - }, { "ImportPath": "golang.org/x/crypto/ssh/terminal", "Rev": "81e90905daefcd6fd217b62423c0908922eadb30" @@ -622,6 +354,14 @@ "ImportPath": "golang.org/x/net/context", "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" }, + { + "ImportPath": "golang.org/x/net/html", + "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + }, + { + "ImportPath": "golang.org/x/net/html/atom", + "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" + }, { "ImportPath": "golang.org/x/net/http2", "Rev": "1c05540f6879653db88113bc4a2b70aec4bd491f" @@ -702,89 +442,65 @@ "ImportPath": "golang.org/x/text/width", "Rev": "b19bf474d317b857955b12035d2c5acb57ce8b01" }, - { - "ImportPath": "golang.org/x/time/rate", - "Rev": "f51c12702a4d776e4c1fa9b0fabab841babae631" - }, - { - "ImportPath": "google.golang.org/genproto/googleapis/api/annotations", - "Rev": "09f6ed296fc66555a25fe4ce95173148778dfa85" - }, { "ImportPath": "google.golang.org/genproto/googleapis/rpc/status", "Rev": "09f6ed296fc66555a25fe4ce95173148778dfa85" }, { "ImportPath": "google.golang.org/grpc", - "Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" - }, - { - "ImportPath": "google.golang.org/grpc/balancer", - "Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" + "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5" }, { "ImportPath": "google.golang.org/grpc/codes", - "Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" - }, - { - "ImportPath": "google.golang.org/grpc/connectivity", - "Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" + "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5" }, { "ImportPath": "google.golang.org/grpc/credentials", - "Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" + "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5" }, { - "ImportPath": "google.golang.org/grpc/grpclb/grpc_lb_v1/messages", - "Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" + "ImportPath": "google.golang.org/grpc/grpclb/grpc_lb_v1", + "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5" }, { "ImportPath": "google.golang.org/grpc/grpclog", - "Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" - }, - { - "ImportPath": "google.golang.org/grpc/health/grpc_health_v1", - "Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" + "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5" }, { "ImportPath": "google.golang.org/grpc/internal", - "Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" + "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5" }, { "ImportPath": "google.golang.org/grpc/keepalive", - "Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" + "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5" }, { "ImportPath": "google.golang.org/grpc/metadata", - "Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" + "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5" }, { "ImportPath": "google.golang.org/grpc/naming", - "Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" + "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5" }, { "ImportPath": "google.golang.org/grpc/peer", - "Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" - }, - { - "ImportPath": "google.golang.org/grpc/resolver", - "Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" + "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5" }, { "ImportPath": "google.golang.org/grpc/stats", - "Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" + "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5" }, { "ImportPath": "google.golang.org/grpc/status", - "Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" + "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5" }, { "ImportPath": "google.golang.org/grpc/tap", - "Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" + "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5" }, { "ImportPath": "google.golang.org/grpc/transport", - "Rev": "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" + "Rev": "d2e1b51f33ff8c5e4a15560ff049d200e83726c5" }, { "ImportPath": "gopkg.in/inf.v0", @@ -796,1271 +512,1183 @@ }, { "ImportPath": "gopkg.in/yaml.v2", - "Rev": "670d4cfef0544295bc27a114dbac37980d83185a" + "Rev": "53feefa2559fb8dfa8d81baad31be332c97d6c77" }, { "ImportPath": "k8s.io/api/admission/v1beta1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/admissionregistration/v1alpha1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/admissionregistration/v1beta1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/apps/v1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/apps/v1beta1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/apps/v1beta2", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/authentication/v1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/authentication/v1beta1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/authorization/v1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/authorization/v1beta1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/autoscaling/v1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/autoscaling/v2beta1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/batch/v1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/batch/v1beta1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/batch/v2alpha1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/certificates/v1beta1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/core/v1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/events/v1beta1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/extensions/v1beta1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/networking/v1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/policy/v1beta1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/rbac/v1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/rbac/v1alpha1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/rbac/v1beta1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/scheduling/v1alpha1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/settings/v1alpha1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/storage/v1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/storage/v1alpha1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/api/storage/v1beta1", - "Rev": "fd252c3a3e1debf912ff5b80221a31a6a3c24493" + "Rev": "9fc595375ab38f53cbc3a53026ac40fb44ad50ca" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/equality", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/errors", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/meta", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" - }, - { - "ImportPath": "k8s.io/apimachinery/pkg/api/meta/table", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/resource", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/testing", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/testing/fuzzer", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/testing/roundtrip", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/validation", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/validation/path", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/apimachinery", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/apimachinery/announced", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/apimachinery/registered", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/fuzzer", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/internalversion", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/validation", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { - "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1beta1", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1alpha1", + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/conversion", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/fields", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/labels", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/schema", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/selection", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/types", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/cache", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/clock", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/diff", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" - }, - { - "ImportPath": "k8s.io/apimachinery/pkg/util/duration", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/errors", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/framer", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/httpstream", + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/intstr", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/json", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/net", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" + }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/proxy", + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/rand", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/runtime", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/sets", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/uuid", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/validation", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/validation/field", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/wait", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/waitgroup", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/util/yaml", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/version", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/pkg/watch", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" + }, + { + "ImportPath": "k8s.io/apimachinery/third_party/forked/golang/netutil", + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect", - "Rev": "e9ff529c66f83aeac6dff90f11ea0c5b7c4d626a" + "Rev": "180eddb345a5be3a157cea1c624700ad5bd27b8f" }, { "ImportPath": "k8s.io/apiserver/pkg/admission", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/admission/configuration", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/admission/initializer", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/admission/metrics", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/admission/plugin/initialization", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/admission/plugin/namespace/lifecycle", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/config", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/config/apis/webhookadmission/v1alpha1", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/errors", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/mutating", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/namespace", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/request", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/rules", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/validating", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/admission/plugin/webhook/versioned", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/apis/apiserver", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/apis/apiserver/install", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/apis/apiserver/v1alpha1", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/apis/audit", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/apis/audit/install", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/apis/audit/v1alpha1", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/apis/audit/v1beta1", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/apis/audit/validation", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/audit", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/audit/policy", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/authentication/authenticator", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/authentication/authenticatorfactory", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/authentication/group", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/authentication/request/anonymous", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/authentication/request/bearertoken", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/authentication/request/headerrequest", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/authentication/request/union", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/authentication/request/websocket", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/authentication/request/x509", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/authentication/serviceaccount", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/authentication/token/tokenfile", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/authentication/user", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/authorization/authorizer", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/authorization/authorizerfactory", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/authorization/union", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/endpoints", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/endpoints/discovery", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/endpoints/filters", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/endpoints/handlers", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/endpoints/handlers/negotiation", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/endpoints/handlers/responsewriters", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/endpoints/metrics", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/endpoints/openapi", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/endpoints/request", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/features", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/registry/generic", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/registry/generic/registry", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" - }, - { - "ImportPath": "k8s.io/apiserver/pkg/registry/generic/testing", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/registry/rest", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" - }, - { - "ImportPath": "k8s.io/apiserver/pkg/registry/rest/resttest", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/server", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/server/filters", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/server/healthz", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/server/httplog", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/server/mux", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/server/options", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" - }, - { - "ImportPath": "k8s.io/apiserver/pkg/server/resourceconfig", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/server/routes", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/server/routes/data/swagger", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/server/storage", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/storage", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/storage/errors", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/storage/etcd", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" - }, - { - "ImportPath": "k8s.io/apiserver/pkg/storage/etcd/etcdtest", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/storage/etcd/metrics", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" - }, - { - "ImportPath": "k8s.io/apiserver/pkg/storage/etcd/testing", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" - }, - { - "ImportPath": "k8s.io/apiserver/pkg/storage/etcd/testing/testingcert", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/storage/etcd/util", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/storage/etcd3", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/storage/etcd3/preflight", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/storage/names", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/storage/storagebackend", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/storage/storagebackend/factory", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" - }, - { - "ImportPath": "k8s.io/apiserver/pkg/storage/testing", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/storage/value", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/util/feature", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" - }, - { - "ImportPath": "k8s.io/apiserver/pkg/util/feature/testing", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/util/flag", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/util/flushwriter", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/util/logs", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/util/trace", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/util/webhook", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/pkg/util/wsstream", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" - }, - { - "ImportPath": "k8s.io/apiserver/plugin/pkg/audit/buffered", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/plugin/pkg/audit/log", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/plugin/pkg/audit/webhook", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/plugin/pkg/authenticator/token/webhook", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/apiserver/plugin/pkg/authorizer/webhook", - "Rev": "6b9d9252a8cdb8736942c1f0d26f71dc592c6f28" + "Rev": "1270e9f1ad9eaf6127691df90af0836f7e152495" }, { "ImportPath": "k8s.io/client-go/discovery", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/discovery/fake", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/dynamic", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/admissionregistration", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/admissionregistration/v1alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/admissionregistration/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/apps", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/apps/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/apps/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/apps/v1beta2", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/autoscaling", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/autoscaling/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/autoscaling/v2beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/batch", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/batch/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/batch/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/batch/v2alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/certificates", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/certificates/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/core", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/core/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/events", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/events/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/extensions", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/extensions/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/internalinterfaces", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/networking", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/networking/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/policy", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/policy/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/rbac", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/rbac/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/rbac/v1alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/rbac/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/scheduling", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/scheduling/v1alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/settings", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/settings/v1alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/storage", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/storage/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/storage/v1alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/informers/storage/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/scheme", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/apps/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/apps/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/apps/v1beta2", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/authentication/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/authentication/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/authorization/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/authorization/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/autoscaling/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v2alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/certificates/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/core/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/events/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/extensions/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/networking/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/policy/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/settings/v1alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/storage/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/storage/v1alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/kubernetes/typed/storage/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/admissionregistration/v1alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/admissionregistration/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/apps/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/apps/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/apps/v1beta2", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/autoscaling/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/autoscaling/v2beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/batch/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/batch/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/batch/v2alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/certificates/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/core/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/events/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/extensions/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/networking/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/policy/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/rbac/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/rbac/v1alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/rbac/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/scheduling/v1alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/settings/v1alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/storage/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/storage/v1alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/listers/storage/v1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" - }, - { - "ImportPath": "k8s.io/client-go/pkg/apis/clientauthentication", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" - }, - { - "ImportPath": "k8s.io/client-go/pkg/apis/clientauthentication/v1alpha1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/pkg/version", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" - }, - { - "ImportPath": "k8s.io/client-go/plugin/pkg/client/auth/exec", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/rest", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/rest/watch", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" - }, - { - "ImportPath": "k8s.io/client-go/scale", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" - }, - { - "ImportPath": "k8s.io/client-go/scale/scheme", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" - }, - { - "ImportPath": "k8s.io/client-go/scale/scheme/appsint", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" - }, - { - "ImportPath": "k8s.io/client-go/scale/scheme/appsv1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" - }, - { - "ImportPath": "k8s.io/client-go/scale/scheme/appsv1beta2", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" - }, - { - "ImportPath": "k8s.io/client-go/scale/scheme/autoscalingv1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" - }, - { - "ImportPath": "k8s.io/client-go/scale/scheme/extensionsint", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" - }, - { - "ImportPath": "k8s.io/client-go/scale/scheme/extensionsv1beta1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/testing", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" - }, - { - "ImportPath": "k8s.io/client-go/third_party/forked/golang/template", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/tools/auth", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/tools/cache", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/tools/clientcmd", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/tools/clientcmd/api", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/tools/clientcmd/api/latest", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/tools/clientcmd/api/v1", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/tools/metrics", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/tools/pager", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/tools/reference", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/transport", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/util/buffer", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/util/cert", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/util/flowcontrol", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/util/homedir", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/util/integer", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" - }, - { - "ImportPath": "k8s.io/client-go/util/jsonpath", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" - }, - { - "ImportPath": "k8s.io/client-go/util/retry", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/client-go/util/workqueue", - "Rev": "a3c9a30b35fc56f709f4428827b807c90af99fc3" + "Rev": "651d7a8818705e25181c672c1d71524a08e42bb0" }, { "ImportPath": "k8s.io/kube-openapi/pkg/builder", - "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" + "Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1" }, { "ImportPath": "k8s.io/kube-openapi/pkg/common", - "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" + "Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1" }, { "ImportPath": "k8s.io/kube-openapi/pkg/handler", - "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" + "Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util", - "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" + "Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" + "Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1" } ] } diff --git a/vendor/k8s.io/apiextensions-apiserver/Godeps/OWNERS b/vendor/k8s.io/apiextensions-apiserver/Godeps/OWNERS deleted file mode 100644 index 3d49f3060..000000000 --- a/vendor/k8s.io/apiextensions-apiserver/Godeps/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -approvers: -- dep-approvers diff --git a/vendor/k8s.io/apiextensions-apiserver/artifacts/example/rc.yaml b/vendor/k8s.io/apiextensions-apiserver/artifacts/example/rc.yaml index 757855627..ac544c60c 100644 --- a/vendor/k8s.io/apiextensions-apiserver/artifacts/example/rc.yaml +++ b/vendor/k8s.io/apiextensions-apiserver/artifacts/example/rc.yaml @@ -23,4 +23,4 @@ spec: - "--etcd-servers=http://localhost:2379" - "--audit-log-path=-" - name: etcd - image: quay.io/coreos/etcd:v3.1.11 + image: quay.io/coreos/etcd:v3.1.10 diff --git a/vendor/k8s.io/apiextensions-apiserver/code-of-conduct.md b/vendor/k8s.io/apiextensions-apiserver/code-of-conduct.md deleted file mode 100644 index 0d15c00cf..000000000 --- a/vendor/k8s.io/apiextensions-apiserver/code-of-conduct.md +++ /dev/null @@ -1,3 +0,0 @@ -# Kubernetes Community Code of Conduct - -Please refer to our [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md) diff --git a/vendor/k8s.io/apiextensions-apiserver/examples/client-go/pkg/apis/cr/v1/zz_generated.deepcopy.go b/vendor/k8s.io/apiextensions-apiserver/examples/client-go/pkg/apis/cr/v1/zz_generated.deepcopy.go index a0399a5ca..fe626ef90 100644 --- a/vendor/k8s.io/apiextensions-apiserver/examples/client-go/pkg/apis/cr/v1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/apiextensions-apiserver/examples/client-go/pkg/apis/cr/v1/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ // +build !ignore_autogenerated /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by deepcopy-gen. DO NOT EDIT. +// This file was autogenerated by deepcopy-gen. Do not edit it manually! package v1 @@ -48,8 +48,9 @@ func (in *Example) DeepCopy() *Example { func (in *Example) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c + } else { + return nil } - return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -81,8 +82,9 @@ func (in *ExampleList) DeepCopy() *ExampleList { func (in *ExampleList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c + } else { + return nil } - return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. diff --git a/vendor/k8s.io/apiextensions-apiserver/examples/client-go/pkg/client/clientset/versioned/fake/register.go b/vendor/k8s.io/apiextensions-apiserver/examples/client-go/pkg/client/clientset/versioned/fake/register.go index 4e6435d2a..f926bc58f 100644 --- a/vendor/k8s.io/apiextensions-apiserver/examples/client-go/pkg/client/clientset/versioned/fake/register.go +++ b/vendor/k8s.io/apiextensions-apiserver/examples/client-go/pkg/client/clientset/versioned/fake/register.go @@ -38,7 +38,7 @@ func init() { // // import ( // "k8s.io/client-go/kubernetes" -// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// clientsetscheme "k8s.io/client-go/kuberentes/scheme" // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" // ) // diff --git a/vendor/k8s.io/apiextensions-apiserver/examples/client-go/pkg/client/clientset/versioned/scheme/register.go b/vendor/k8s.io/apiextensions-apiserver/examples/client-go/pkg/client/clientset/versioned/scheme/register.go index 311152e38..e37edaa5d 100644 --- a/vendor/k8s.io/apiextensions-apiserver/examples/client-go/pkg/client/clientset/versioned/scheme/register.go +++ b/vendor/k8s.io/apiextensions-apiserver/examples/client-go/pkg/client/clientset/versioned/scheme/register.go @@ -38,7 +38,7 @@ func init() { // // import ( // "k8s.io/client-go/kubernetes" -// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// clientsetscheme "k8s.io/client-go/kuberentes/scheme" // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" // ) // diff --git a/vendor/k8s.io/apiextensions-apiserver/hack/boilerplate.go.txt b/vendor/k8s.io/apiextensions-apiserver/hack/boilerplate.go.txt deleted file mode 100644 index 59e740c1e..000000000 --- a/vendor/k8s.io/apiextensions-apiserver/hack/boilerplate.go.txt +++ /dev/null @@ -1,16 +0,0 @@ -/* -Copyright YEAR The Kubernetes 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. -*/ - diff --git a/vendor/k8s.io/apiextensions-apiserver/hack/update-codegen.sh b/vendor/k8s.io/apiextensions-apiserver/hack/update-codegen.sh index 9c98ebf4d..efc52ecd8 100755 --- a/vendor/k8s.io/apiextensions-apiserver/hack/update-codegen.sh +++ b/vendor/k8s.io/apiextensions-apiserver/hack/update-codegen.sh @@ -40,7 +40,7 @@ function cleanup { trap cleanup EXIT echo "Building client-gen" -CLIENTGEN="${PWD}/client-gen" +CLIENTGEN="${PWD}/client-gen-binary" go build -o "${CLIENTGEN}" ${CODEGEN_PKG}/cmd/client-gen PREFIX=k8s.io/apiextensions-apiserver/pkg/apis @@ -50,10 +50,10 @@ apiextensions/ apiextensions/v1beta1 ) INPUT="--input ${INPUT_APIS[@]}" -CLIENTSET_PATH="--output-package k8s.io/apiextensions-apiserver/pkg/client/clientset" +CLIENTSET_PATH="--clientset-path k8s.io/apiextensions-apiserver/pkg/client/clientset" ${CLIENTGEN} ${INPUT_BASE} ${INPUT} ${CLIENTSET_PATH} --output-base ${SCRIPT_BASE} -${CLIENTGEN} --clientset-name="clientset" ${INPUT_BASE} --input apiextensions/v1beta1 ${CLIENTSET_PATH} --output-base ${SCRIPT_BASE} --go-header-file ${SCRIPT_ROOT}/hack/boilerplate.go.txt +${CLIENTGEN} --clientset-name="clientset" ${INPUT_BASE} --input apiextensions/v1beta1 ${CLIENTSET_PATH} --output-base ${SCRIPT_BASE} echo "Building lister-gen" @@ -62,7 +62,7 @@ go build -o "${listergen}" ${CODEGEN_PKG}/cmd/lister-gen LISTER_INPUT="--input-dirs k8s.io/apiextensions-apiserver/pkg/apis/apiextensions --input-dirs k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" LISTER_PATH="--output-package k8s.io/apiextensions-apiserver/pkg/client/listers" -${listergen} ${LISTER_INPUT} ${LISTER_PATH} --output-base ${SCRIPT_BASE} --go-header-file ${SCRIPT_ROOT}/hack/boilerplate.go.txt +${listergen} ${LISTER_INPUT} ${LISTER_PATH} --output-base ${SCRIPT_BASE} echo "Building informer-gen" @@ -75,6 +75,5 @@ ${informergen} \ --versioned-clientset-package k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset \ --internal-clientset-package k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset \ --listers-package k8s.io/apiextensions-apiserver/pkg/client/listers \ - --output-package k8s.io/apiextensions-apiserver/pkg/client/informers \ - --go-header-file ${SCRIPT_ROOT}/hack/boilerplate.go.txt + --output-package k8s.io/apiextensions-apiserver/pkg/client/informers "$@" diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/BUILD b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/BUILD index b2ea73c41..303d94b93 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/BUILD +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/BUILD @@ -28,7 +28,8 @@ go_library( go_test( name = "go_default_test", srcs = ["helpers_test.go"], - embed = [":go_default_library"], + importpath = "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions", + library = ":go_default_library", deps = ["//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library"], ) diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer/fuzzer.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer/fuzzer.go index a7cfb0ae7..fcde56968 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer/fuzzer.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer/fuzzer.go @@ -60,6 +60,22 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} { } if isValue || c.Intn(10) == 0 { c.Fuzz(vobj.Field(i).Addr().Interface()) + + // JSON keys must not contain escape char with our JSON codec (jsoniter) + // TODO: remove this when/if we moved from jsoniter.ConfigFastest to ConfigCompatibleWithStandardLibrary + if field.Type.Kind() == reflect.Map { + keys := append([]reflect.Value(nil), vobj.Field(i).MapKeys()...) + for _, k := range keys { + stripped := toJSONString(k.String()) + if stripped == k.String() { + continue + } + // set new key + vobj.Field(i).SetMapIndex(reflect.ValueOf(stripped), vobj.Field(i).MapIndex(k)) + // remove old + vobj.Field(i).SetMapIndex(k, reflect.Value{}) + } + } } } } @@ -109,3 +125,13 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} { }, } } + +func toJSONString(s string) string { + return strings.Map(func(r rune) rune { + // replace chars which are not supported in keys by jsoniter.ConfigFastest + if r == '\\' || r == '"' { + return 'x' + } + return r + }, s) +} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install/BUILD b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install/BUILD index e7403207c..3a0a056a2 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install/BUILD +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install/BUILD @@ -9,7 +9,8 @@ load( go_test( name = "go_default_test", srcs = ["roundtrip_test.go"], - embed = [":go_default_library"], + importpath = "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install", + library = ":go_default_library", deps = [ "//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/fuzzer:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/testing/roundtrip:go_default_library", diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types.go index 0deb7cbd0..880da65ce 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/types.go @@ -16,9 +16,7 @@ limitations under the License. package apiextensions -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) +import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" // CustomResourceDefinitionSpec describes how a user wants their resource to appear type CustomResourceDefinitionSpec struct { @@ -32,8 +30,6 @@ type CustomResourceDefinitionSpec struct { Scope ResourceScope // Validation describes the validation methods for CustomResources Validation *CustomResourceValidation - // Subresources describes the subresources for CustomResources - Subresources *CustomResourceSubresources } // CustomResourceDefinitionNames indicates the names to serve this CustomResourceDefinition @@ -49,9 +45,6 @@ type CustomResourceDefinitionNames struct { Kind string // ListKind is the serialized kind of the list for this resource. Defaults to <kind>List. ListKind string - // Categories is a list of grouped resources custom resources belong to (e.g. 'all') - // +optional - Categories []string } // ResourceScope is an enum defining the different scopes available to a custom resource @@ -153,41 +146,3 @@ type CustomResourceValidation struct { // OpenAPIV3Schema is the OpenAPI v3 schema to be validated against. OpenAPIV3Schema *JSONSchemaProps } - -// CustomResourceSubresources defines the status and scale subresources for CustomResources. -type CustomResourceSubresources struct { - // Status denotes the status subresource for CustomResources - Status *CustomResourceSubresourceStatus - // Scale denotes the scale subresource for CustomResources - Scale *CustomResourceSubresourceScale -} - -// CustomResourceSubresourceStatus defines how to serve the status subresource for CustomResources. -// Status is represented by the `.status` JSON path inside of a CustomResource. When set, -// * exposes a /status subresource for the custom resource -// * PUT requests to the /status subresource take a custom resource object, and ignore changes to anything except the status stanza -// * PUT/POST/PATCH requests to the custom resource ignore changes to the status stanza -type CustomResourceSubresourceStatus struct{} - -// CustomResourceSubresourceScale defines how to serve the scale subresource for CustomResources. -type CustomResourceSubresourceScale struct { - // SpecReplicasPath defines the JSON path inside of a CustomResource that corresponds to Scale.Spec.Replicas. - // Only JSON paths without the array notation are allowed. - // Must be a JSON Path under .spec. - // If there is no value under the given path in the CustomResource, the /scale subresource will return an error on GET. - SpecReplicasPath string - // StatusReplicasPath defines the JSON path inside of a CustomResource that corresponds to Scale.Status.Replicas. - // Only JSON paths without the array notation are allowed. - // Must be a JSON Path under .status. - // If there is no value under the given path in the CustomResource, the status replica value in the /scale subresource - // will default to 0. - StatusReplicasPath string - // LabelSelectorPath defines the JSON path inside of a CustomResource that corresponds to Scale.Status.Selector. - // Only JSON paths without the array notation are allowed. - // Must be a JSON Path under .status. - // Must be set to work with HPA. - // If there is no value under the given path in the CustomResource, the status label selector value in the /scale - // subresource will default to the empty string. - // +optional - LabelSelectorPath *string -} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/BUILD b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/BUILD index 972732d4a..32f2ab8fe 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/BUILD +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/BUILD @@ -60,7 +60,8 @@ go_test( "conversion_test.go", "marshal_test.go", ], - embed = [":go_default_library"], + importpath = "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1", + library = ":go_default_library", deps = [ "//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.pb.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.pb.go index e7325da23..e9b16e6db 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.pb.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.pb.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -31,9 +31,6 @@ limitations under the License. CustomResourceDefinitionNames CustomResourceDefinitionSpec CustomResourceDefinitionStatus - CustomResourceSubresourceScale - CustomResourceSubresourceStatus - CustomResourceSubresources CustomResourceValidation ExternalDocumentation JSON @@ -102,54 +99,36 @@ func (*CustomResourceDefinitionStatus) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{5} } -func (m *CustomResourceSubresourceScale) Reset() { *m = CustomResourceSubresourceScale{} } -func (*CustomResourceSubresourceScale) ProtoMessage() {} -func (*CustomResourceSubresourceScale) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{6} -} - -func (m *CustomResourceSubresourceStatus) Reset() { *m = CustomResourceSubresourceStatus{} } -func (*CustomResourceSubresourceStatus) ProtoMessage() {} -func (*CustomResourceSubresourceStatus) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{7} -} - -func (m *CustomResourceSubresources) Reset() { *m = CustomResourceSubresources{} } -func (*CustomResourceSubresources) ProtoMessage() {} -func (*CustomResourceSubresources) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{8} -} - func (m *CustomResourceValidation) Reset() { *m = CustomResourceValidation{} } func (*CustomResourceValidation) ProtoMessage() {} func (*CustomResourceValidation) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{9} + return fileDescriptorGenerated, []int{6} } func (m *ExternalDocumentation) Reset() { *m = ExternalDocumentation{} } func (*ExternalDocumentation) ProtoMessage() {} -func (*ExternalDocumentation) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{10} } +func (*ExternalDocumentation) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{7} } func (m *JSON) Reset() { *m = JSON{} } func (*JSON) ProtoMessage() {} -func (*JSON) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{11} } +func (*JSON) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{8} } func (m *JSONSchemaProps) Reset() { *m = JSONSchemaProps{} } func (*JSONSchemaProps) ProtoMessage() {} -func (*JSONSchemaProps) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{12} } +func (*JSONSchemaProps) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{9} } func (m *JSONSchemaPropsOrArray) Reset() { *m = JSONSchemaPropsOrArray{} } func (*JSONSchemaPropsOrArray) ProtoMessage() {} -func (*JSONSchemaPropsOrArray) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{13} } +func (*JSONSchemaPropsOrArray) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{10} } func (m *JSONSchemaPropsOrBool) Reset() { *m = JSONSchemaPropsOrBool{} } func (*JSONSchemaPropsOrBool) ProtoMessage() {} -func (*JSONSchemaPropsOrBool) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{14} } +func (*JSONSchemaPropsOrBool) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{11} } func (m *JSONSchemaPropsOrStringArray) Reset() { *m = JSONSchemaPropsOrStringArray{} } func (*JSONSchemaPropsOrStringArray) ProtoMessage() {} func (*JSONSchemaPropsOrStringArray) Descriptor() ([]byte, []int) { - return fileDescriptorGenerated, []int{15} + return fileDescriptorGenerated, []int{12} } func init() { @@ -159,9 +138,6 @@ func init() { proto.RegisterType((*CustomResourceDefinitionNames)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinitionNames") proto.RegisterType((*CustomResourceDefinitionSpec)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinitionSpec") proto.RegisterType((*CustomResourceDefinitionStatus)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceDefinitionStatus") - proto.RegisterType((*CustomResourceSubresourceScale)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceSubresourceScale") - proto.RegisterType((*CustomResourceSubresourceStatus)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceSubresourceStatus") - proto.RegisterType((*CustomResourceSubresources)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceSubresources") proto.RegisterType((*CustomResourceValidation)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceValidation") proto.RegisterType((*ExternalDocumentation)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.ExternalDocumentation") proto.RegisterType((*JSON)(nil), "k8s.io.apiextensions_apiserver.pkg.apis.apiextensions.v1beta1.JSON") @@ -338,21 +314,6 @@ func (m *CustomResourceDefinitionNames) MarshalTo(dAtA []byte) (int, error) { i++ i = encodeVarintGenerated(dAtA, i, uint64(len(m.ListKind))) i += copy(dAtA[i:], m.ListKind) - if len(m.Categories) > 0 { - for _, s := range m.Categories { - dAtA[i] = 0x32 - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } return i, nil } @@ -401,16 +362,6 @@ func (m *CustomResourceDefinitionSpec) MarshalTo(dAtA []byte) (int, error) { } i += n7 } - if m.Subresources != nil { - dAtA[i] = 0x32 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Subresources.Size())) - n8, err := m.Subresources.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n8 - } return i, nil } @@ -444,99 +395,11 @@ func (m *CustomResourceDefinitionStatus) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.AcceptedNames.Size())) - n9, err := m.AcceptedNames.MarshalTo(dAtA[i:]) + n8, err := m.AcceptedNames.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n9 - return i, nil -} - -func (m *CustomResourceSubresourceScale) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *CustomResourceSubresourceScale) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.SpecReplicasPath))) - i += copy(dAtA[i:], m.SpecReplicasPath) - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(m.StatusReplicasPath))) - i += copy(dAtA[i:], m.StatusReplicasPath) - if m.LabelSelectorPath != nil { - dAtA[i] = 0x1a - i++ - i = encodeVarintGenerated(dAtA, i, uint64(len(*m.LabelSelectorPath))) - i += copy(dAtA[i:], *m.LabelSelectorPath) - } - return i, nil -} - -func (m *CustomResourceSubresourceStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *CustomResourceSubresourceStatus) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - return i, nil -} - -func (m *CustomResourceSubresources) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *CustomResourceSubresources) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Status != nil { - dAtA[i] = 0xa - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Status.Size())) - n10, err := m.Status.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n10 - } - if m.Scale != nil { - dAtA[i] = 0x12 - i++ - i = encodeVarintGenerated(dAtA, i, uint64(m.Scale.Size())) - n11, err := m.Scale.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n11 - } + i += n8 return i, nil } @@ -559,11 +422,11 @@ func (m *CustomResourceValidation) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.OpenAPIV3Schema.Size())) - n12, err := m.OpenAPIV3Schema.MarshalTo(dAtA[i:]) + n9, err := m.OpenAPIV3Schema.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n12 + i += n9 } return i, nil } @@ -667,11 +530,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x42 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Default.Size())) - n13, err := m.Default.MarshalTo(dAtA[i:]) + n10, err := m.Default.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n13 + i += n10 } if m.Maximum != nil { dAtA[i] = 0x49 @@ -795,11 +658,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Items.Size())) - n14, err := m.Items.MarshalTo(dAtA[i:]) + n11, err := m.Items.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n14 + i += n11 } if len(m.AllOf) > 0 { for _, msg := range m.AllOf { @@ -849,11 +712,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Not.Size())) - n15, err := m.Not.MarshalTo(dAtA[i:]) + n12, err := m.Not.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n15 + i += n12 } if len(m.Properties) > 0 { keysForProperties := make([]string, 0, len(m.Properties)) @@ -881,11 +744,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64((&v).Size())) - n16, err := (&v).MarshalTo(dAtA[i:]) + n13, err := (&v).MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n16 + i += n13 } } if m.AdditionalProperties != nil { @@ -894,11 +757,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.AdditionalProperties.Size())) - n17, err := m.AdditionalProperties.MarshalTo(dAtA[i:]) + n14, err := m.AdditionalProperties.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n17 + i += n14 } if len(m.PatternProperties) > 0 { keysForPatternProperties := make([]string, 0, len(m.PatternProperties)) @@ -926,11 +789,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64((&v).Size())) - n18, err := (&v).MarshalTo(dAtA[i:]) + n15, err := (&v).MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n18 + i += n15 } } if len(m.Dependencies) > 0 { @@ -959,11 +822,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64((&v).Size())) - n19, err := (&v).MarshalTo(dAtA[i:]) + n16, err := (&v).MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n19 + i += n16 } } if m.AdditionalItems != nil { @@ -972,11 +835,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.AdditionalItems.Size())) - n20, err := m.AdditionalItems.MarshalTo(dAtA[i:]) + n17, err := m.AdditionalItems.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n20 + i += n17 } if len(m.Definitions) > 0 { keysForDefinitions := make([]string, 0, len(m.Definitions)) @@ -1004,11 +867,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64((&v).Size())) - n21, err := (&v).MarshalTo(dAtA[i:]) + n18, err := (&v).MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n21 + i += n18 } } if m.ExternalDocs != nil { @@ -1017,11 +880,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.ExternalDocs.Size())) - n22, err := m.ExternalDocs.MarshalTo(dAtA[i:]) + n19, err := m.ExternalDocs.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n22 + i += n19 } if m.Example != nil { dAtA[i] = 0xa2 @@ -1029,11 +892,11 @@ func (m *JSONSchemaProps) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Example.Size())) - n23, err := m.Example.MarshalTo(dAtA[i:]) + n20, err := m.Example.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n23 + i += n20 } return i, nil } @@ -1057,11 +920,11 @@ func (m *JSONSchemaPropsOrArray) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Schema.Size())) - n24, err := m.Schema.MarshalTo(dAtA[i:]) + n21, err := m.Schema.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n24 + i += n21 } if len(m.JSONSchemas) > 0 { for _, msg := range m.JSONSchemas { @@ -1105,11 +968,11 @@ func (m *JSONSchemaPropsOrBool) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Schema.Size())) - n25, err := m.Schema.MarshalTo(dAtA[i:]) + n22, err := m.Schema.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n25 + i += n22 } return i, nil } @@ -1133,11 +996,11 @@ func (m *JSONSchemaPropsOrStringArray) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintGenerated(dAtA, i, uint64(m.Schema.Size())) - n26, err := m.Schema.MarshalTo(dAtA[i:]) + n23, err := m.Schema.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n26 + i += n23 } if len(m.Property) > 0 { for _, s := range m.Property { @@ -1243,12 +1106,6 @@ func (m *CustomResourceDefinitionNames) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.ListKind) n += 1 + l + sovGenerated(uint64(l)) - if len(m.Categories) > 0 { - for _, s := range m.Categories { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } return n } @@ -1267,10 +1124,6 @@ func (m *CustomResourceDefinitionSpec) Size() (n int) { l = m.Validation.Size() n += 1 + l + sovGenerated(uint64(l)) } - if m.Subresources != nil { - l = m.Subresources.Size() - n += 1 + l + sovGenerated(uint64(l)) - } return n } @@ -1288,40 +1141,6 @@ func (m *CustomResourceDefinitionStatus) Size() (n int) { return n } -func (m *CustomResourceSubresourceScale) Size() (n int) { - var l int - _ = l - l = len(m.SpecReplicasPath) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.StatusReplicasPath) - n += 1 + l + sovGenerated(uint64(l)) - if m.LabelSelectorPath != nil { - l = len(*m.LabelSelectorPath) - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - -func (m *CustomResourceSubresourceStatus) Size() (n int) { - var l int - _ = l - return n -} - -func (m *CustomResourceSubresources) Size() (n int) { - var l int - _ = l - if m.Status != nil { - l = m.Status.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - if m.Scale != nil { - l = m.Scale.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n -} - func (m *CustomResourceValidation) Size() (n int) { var l int _ = l @@ -1603,7 +1422,6 @@ func (this *CustomResourceDefinitionNames) String() string { `ShortNames:` + fmt.Sprintf("%v", this.ShortNames) + `,`, `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, `ListKind:` + fmt.Sprintf("%v", this.ListKind) + `,`, - `Categories:` + fmt.Sprintf("%v", this.Categories) + `,`, `}`, }, "") return s @@ -1618,7 +1436,6 @@ func (this *CustomResourceDefinitionSpec) String() string { `Names:` + strings.Replace(strings.Replace(this.Names.String(), "CustomResourceDefinitionNames", "CustomResourceDefinitionNames", 1), `&`, ``, 1) + `,`, `Scope:` + fmt.Sprintf("%v", this.Scope) + `,`, `Validation:` + strings.Replace(fmt.Sprintf("%v", this.Validation), "CustomResourceValidation", "CustomResourceValidation", 1) + `,`, - `Subresources:` + strings.Replace(fmt.Sprintf("%v", this.Subresources), "CustomResourceSubresources", "CustomResourceSubresources", 1) + `,`, `}`, }, "") return s @@ -1634,38 +1451,6 @@ func (this *CustomResourceDefinitionStatus) String() string { }, "") return s } -func (this *CustomResourceSubresourceScale) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&CustomResourceSubresourceScale{`, - `SpecReplicasPath:` + fmt.Sprintf("%v", this.SpecReplicasPath) + `,`, - `StatusReplicasPath:` + fmt.Sprintf("%v", this.StatusReplicasPath) + `,`, - `LabelSelectorPath:` + valueToStringGenerated(this.LabelSelectorPath) + `,`, - `}`, - }, "") - return s -} -func (this *CustomResourceSubresourceStatus) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&CustomResourceSubresourceStatus{`, - `}`, - }, "") - return s -} -func (this *CustomResourceSubresources) String() string { - if this == nil { - return "nil" - } - s := strings.Join([]string{`&CustomResourceSubresources{`, - `Status:` + strings.Replace(fmt.Sprintf("%v", this.Status), "CustomResourceSubresourceStatus", "CustomResourceSubresourceStatus", 1) + `,`, - `Scale:` + strings.Replace(fmt.Sprintf("%v", this.Scale), "CustomResourceSubresourceScale", "CustomResourceSubresourceScale", 1) + `,`, - `}`, - }, "") - return s -} func (this *CustomResourceValidation) String() string { if this == nil { return "nil" @@ -2444,35 +2229,6 @@ func (m *CustomResourceDefinitionNames) Unmarshal(dAtA []byte) error { } m.ListKind = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Categories", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Categories = append(m.Categories, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -2673,39 +2429,6 @@ func (m *CustomResourceDefinitionSpec) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Subresources", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Subresources == nil { - m.Subresources = &CustomResourceSubresources{} - } - if err := m.Subresources.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -2838,310 +2561,6 @@ func (m *CustomResourceDefinitionStatus) Unmarshal(dAtA []byte) error { } return nil } -func (m *CustomResourceSubresourceScale) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: CustomResourceSubresourceScale: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: CustomResourceSubresourceScale: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SpecReplicasPath", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SpecReplicasPath = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StatusReplicasPath", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.StatusReplicasPath = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LabelSelectorPath", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.LabelSelectorPath = &s - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *CustomResourceSubresourceStatus) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: CustomResourceSubresourceStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: CustomResourceSubresourceStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *CustomResourceSubresources) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: CustomResourceSubresources: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: CustomResourceSubresources: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Status == nil { - m.Status = &CustomResourceSubresourceStatus{} - } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Scale", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Scale == nil { - m.Scale = &CustomResourceSubresourceScale{} - } - if err := m.Scale.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *CustomResourceValidation) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -5241,137 +4660,125 @@ func init() { } var fileDescriptorGenerated = []byte{ - // 2102 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x58, 0xcb, 0x6f, 0x63, 0x49, - 0xd5, 0x4f, 0xd9, 0x79, 0x56, 0x92, 0x49, 0x52, 0xdd, 0xe9, 0xef, 0x76, 0xbe, 0x6e, 0x3b, 0xf1, - 0x30, 0xa3, 0x00, 0xd3, 0x36, 0x3d, 0x0f, 0x66, 0x40, 0x62, 0x11, 0x27, 0x01, 0xf5, 0x90, 0x74, - 0xa2, 0x72, 0x77, 0x23, 0x98, 0x67, 0xe5, 0xba, 0xec, 0x54, 0xe7, 0xbe, 0xfa, 0x56, 0x5d, 0x77, - 0x22, 0x01, 0xe2, 0xa1, 0x11, 0x12, 0x12, 0x0f, 0x41, 0x6f, 0x90, 0xd8, 0x80, 0xc4, 0x06, 0x21, - 0x58, 0xc0, 0x92, 0x25, 0x8b, 0x5e, 0x8e, 0xc4, 0x66, 0x56, 0x16, 0x6d, 0xfe, 0x05, 0x24, 0xa4, - 0xac, 0x50, 0x3d, 0xee, 0xcb, 0x8e, 0x67, 0x5a, 0x1a, 0x7b, 0x7a, 0xe7, 0x7b, 0x5e, 0xbf, 0x5f, - 0x9d, 0x3a, 0x75, 0xea, 0x94, 0x61, 0xeb, 0xe4, 0x0d, 0x5e, 0x65, 0x7e, 0xed, 0x24, 0x3a, 0xa2, - 0xa1, 0x47, 0x05, 0xe5, 0xb5, 0x0e, 0xf5, 0x9a, 0x7e, 0x58, 0x33, 0x0a, 0x12, 0x30, 0x7a, 0x2a, - 0xa8, 0xc7, 0x99, 0xef, 0xf1, 0x1b, 0x24, 0x60, 0x9c, 0x86, 0x1d, 0x1a, 0xd6, 0x82, 0x93, 0xb6, - 0xd4, 0xf1, 0xbc, 0x41, 0xad, 0x73, 0xf3, 0x88, 0x0a, 0x72, 0xb3, 0xd6, 0xa6, 0x1e, 0x0d, 0x89, - 0xa0, 0xcd, 0x6a, 0x10, 0xfa, 0xc2, 0x47, 0x5f, 0xd3, 0xe1, 0xaa, 0x39, 0xeb, 0xf7, 0x92, 0x70, - 0xd5, 0xe0, 0xa4, 0x2d, 0x75, 0x3c, 0x6f, 0x50, 0x35, 0xe1, 0xd6, 0x6e, 0xb4, 0x99, 0x38, 0x8e, - 0x8e, 0xaa, 0xb6, 0xef, 0xd6, 0xda, 0x7e, 0xdb, 0xaf, 0xa9, 0xa8, 0x47, 0x51, 0x4b, 0x7d, 0xa9, - 0x0f, 0xf5, 0x4b, 0xa3, 0xad, 0xbd, 0x9a, 0x92, 0x77, 0x89, 0x7d, 0xcc, 0x3c, 0x1a, 0x9e, 0xa5, - 0x8c, 0x5d, 0x2a, 0x48, 0xad, 0x33, 0xc0, 0x71, 0xad, 0x36, 0xcc, 0x2b, 0x8c, 0x3c, 0xc1, 0x5c, - 0x3a, 0xe0, 0xf0, 0xe5, 0x4f, 0x72, 0xe0, 0xf6, 0x31, 0x75, 0xc9, 0x80, 0xdf, 0x2b, 0xc3, 0xfc, - 0x22, 0xc1, 0x9c, 0x1a, 0xf3, 0x04, 0x17, 0x61, 0xbf, 0x53, 0xe5, 0xc7, 0x45, 0x68, 0x6d, 0x47, - 0x5c, 0xf8, 0x2e, 0xa6, 0xdc, 0x8f, 0x42, 0x9b, 0xee, 0xd0, 0x16, 0xf3, 0x98, 0x60, 0xbe, 0x87, - 0xde, 0x87, 0xb3, 0x72, 0x55, 0x4d, 0x22, 0x88, 0x05, 0xd6, 0xc1, 0xe6, 0xfc, 0xcb, 0x5f, 0xaa, - 0xa6, 0x19, 0x4f, 0x40, 0xd2, 0x34, 0x4b, 0xeb, 0x6a, 0xe7, 0x66, 0xf5, 0xe0, 0xe8, 0x3e, 0xb5, - 0xc5, 0x3e, 0x15, 0xa4, 0x8e, 0x1e, 0x77, 0xcb, 0x13, 0xbd, 0x6e, 0x19, 0xa6, 0x32, 0x9c, 0x44, - 0x45, 0xdf, 0x83, 0x93, 0x3c, 0xa0, 0xb6, 0x55, 0x50, 0xd1, 0xdf, 0xaa, 0x7e, 0xaa, 0xfd, 0xac, - 0x0e, 0x5b, 0x48, 0x23, 0xa0, 0x76, 0x7d, 0xc1, 0x10, 0x99, 0x94, 0x5f, 0x58, 0xc1, 0xa2, 0x0f, - 0x00, 0x9c, 0xe6, 0x82, 0x88, 0x88, 0x5b, 0x45, 0xc5, 0xe0, 0x9d, 0x71, 0x31, 0x50, 0x20, 0xf5, - 0xe7, 0x0c, 0x87, 0x69, 0xfd, 0x8d, 0x0d, 0x78, 0xe5, 0x3f, 0x05, 0xb8, 0x31, 0xcc, 0x75, 0xdb, - 0xf7, 0x9a, 0x7a, 0x3b, 0x6e, 0xc1, 0x49, 0x71, 0x16, 0x50, 0xb5, 0x15, 0x73, 0xf5, 0xd7, 0xe2, - 0xf5, 0xdc, 0x39, 0x0b, 0xe8, 0x79, 0xb7, 0xfc, 0xc2, 0x27, 0x06, 0x90, 0x86, 0x58, 0x85, 0x40, - 0x5f, 0x49, 0xd6, 0x5d, 0x50, 0xc1, 0x36, 0xf2, 0xc4, 0xce, 0xbb, 0xe5, 0xa5, 0xc4, 0x2d, 0xcf, - 0x15, 0x75, 0x20, 0x72, 0x08, 0x17, 0x77, 0x42, 0xe2, 0x71, 0x1d, 0x96, 0xb9, 0xd4, 0xa4, 0xef, - 0x0b, 0x4f, 0x57, 0x1e, 0xd2, 0xa3, 0xbe, 0x66, 0x20, 0xd1, 0xde, 0x40, 0x34, 0x7c, 0x01, 0x02, - 0x7a, 0x11, 0x4e, 0x87, 0x94, 0x70, 0xdf, 0xb3, 0x26, 0x15, 0xe5, 0x24, 0x97, 0x58, 0x49, 0xb1, - 0xd1, 0xa2, 0xcf, 0xc3, 0x19, 0x97, 0x72, 0x4e, 0xda, 0xd4, 0x9a, 0x52, 0x86, 0x4b, 0xc6, 0x70, - 0x66, 0x5f, 0x8b, 0x71, 0xac, 0xaf, 0x9c, 0x03, 0x78, 0x6d, 0x58, 0xd6, 0xf6, 0x18, 0x17, 0xe8, - 0xed, 0x81, 0x03, 0x50, 0x7d, 0xba, 0x15, 0x4a, 0x6f, 0x55, 0xfe, 0xcb, 0x06, 0x7c, 0x36, 0x96, - 0x64, 0x8a, 0xff, 0xbb, 0x70, 0x8a, 0x09, 0xea, 0xca, 0x3d, 0x28, 0x6e, 0xce, 0xbf, 0xfc, 0xad, - 0x31, 0xd5, 0x5e, 0x7d, 0xd1, 0x70, 0x98, 0xba, 0x25, 0xd1, 0xb0, 0x06, 0xad, 0xfc, 0xa1, 0x00, - 0xaf, 0x0f, 0x73, 0xb9, 0x4d, 0x5c, 0xca, 0x65, 0xc6, 0x03, 0x27, 0x0a, 0x89, 0x63, 0x2a, 0x2e, - 0xc9, 0xf8, 0xa1, 0x92, 0x62, 0xa3, 0x45, 0x2f, 0xc1, 0x59, 0xce, 0xbc, 0x76, 0xe4, 0x90, 0xd0, - 0x94, 0x53, 0xb2, 0xea, 0x86, 0x91, 0xe3, 0xc4, 0x02, 0x55, 0x21, 0xe4, 0xc7, 0x7e, 0x28, 0x14, - 0x86, 0x55, 0x5c, 0x2f, 0xca, 0xc8, 0xb2, 0x41, 0x34, 0x12, 0x29, 0xce, 0x58, 0xa0, 0x75, 0x38, - 0x79, 0xc2, 0xbc, 0xa6, 0xd9, 0xf5, 0xe4, 0x14, 0x7f, 0x93, 0x79, 0x4d, 0xac, 0x34, 0x12, 0xdf, - 0x61, 0x5c, 0x48, 0x89, 0xd9, 0xf2, 0x5c, 0xd6, 0x95, 0x65, 0x62, 0x21, 0xf1, 0x6d, 0x22, 0x68, - 0xdb, 0x0f, 0x19, 0xe5, 0xd6, 0x74, 0x8a, 0xbf, 0x9d, 0x48, 0x71, 0xc6, 0xa2, 0xf2, 0x8f, 0xc9, - 0xe1, 0x45, 0x22, 0x5b, 0x09, 0x7a, 0x1e, 0x4e, 0xb5, 0x43, 0x3f, 0x0a, 0x4c, 0x96, 0x92, 0x6c, - 0x7f, 0x43, 0x0a, 0xb1, 0xd6, 0xc9, 0xaa, 0xec, 0xd0, 0x50, 0x6e, 0x98, 0x49, 0x51, 0x52, 0x95, - 0xf7, 0xb4, 0x18, 0xc7, 0x7a, 0xf4, 0x43, 0x00, 0xa7, 0x3c, 0x93, 0x1c, 0x59, 0x72, 0x6f, 0x8f, - 0xa9, 0x2e, 0x54, 0x7a, 0x53, 0xba, 0x3a, 0xf3, 0x1a, 0x19, 0xbd, 0x0a, 0xa7, 0xb8, 0xed, 0x07, - 0xd4, 0x64, 0xbd, 0x14, 0x1b, 0x35, 0xa4, 0xf0, 0xbc, 0x5b, 0x5e, 0x8c, 0xc3, 0x29, 0x01, 0xd6, - 0xc6, 0xe8, 0x27, 0x00, 0xc2, 0x0e, 0x71, 0x58, 0x93, 0xc8, 0xf8, 0x6a, 0x2f, 0x46, 0x5d, 0xd6, - 0xf7, 0x92, 0xf0, 0x7a, 0xd3, 0xd2, 0x6f, 0x9c, 0x81, 0x46, 0xbf, 0x00, 0x70, 0x81, 0x47, 0x47, - 0xa1, 0xf1, 0x92, 0xfb, 0x2c, 0xb9, 0x7c, 0x7b, 0xa4, 0x5c, 0x1a, 0x19, 0x80, 0xfa, 0x72, 0xaf, - 0x5b, 0x5e, 0xc8, 0x4a, 0x70, 0x8e, 0x40, 0xe5, 0x9f, 0x05, 0x58, 0xfa, 0xf8, 0xdb, 0x01, 0x3d, - 0x02, 0x10, 0xda, 0x71, 0xd7, 0xe5, 0x16, 0x50, 0x5d, 0xe1, 0xfd, 0x31, 0xed, 0x7e, 0xd2, 0xde, - 0xd3, 0x1b, 0x3a, 0x11, 0xc9, 0x03, 0x90, 0xfc, 0x46, 0xbf, 0x01, 0x70, 0x91, 0xd8, 0x36, 0x0d, - 0x04, 0x6d, 0xea, 0x43, 0x5b, 0xf8, 0x0c, 0xea, 0x72, 0xd5, 0xb0, 0x5a, 0xdc, 0xca, 0x42, 0xe3, - 0x3c, 0x93, 0xca, 0x7f, 0x41, 0x7f, 0x56, 0x33, 0x5b, 0xd0, 0xb0, 0x89, 0x43, 0xd1, 0x0e, 0x5c, - 0x96, 0x77, 0x3d, 0xa6, 0x81, 0xc3, 0x6c, 0xc2, 0x0f, 0x89, 0x38, 0x36, 0x27, 0xd5, 0x32, 0x10, - 0xcb, 0x8d, 0x3e, 0x3d, 0x1e, 0xf0, 0x40, 0x6f, 0x42, 0xa4, 0xef, 0xbf, 0x5c, 0x1c, 0x7d, 0x94, - 0x93, 0x9b, 0xac, 0x31, 0x60, 0x81, 0x2f, 0xf0, 0x42, 0xdb, 0x70, 0xc5, 0x21, 0x47, 0xd4, 0x69, - 0x50, 0x87, 0xda, 0xc2, 0x0f, 0x55, 0xa8, 0xa2, 0x0a, 0xb5, 0xda, 0xeb, 0x96, 0x57, 0xf6, 0xfa, - 0x95, 0x78, 0xd0, 0xbe, 0xb2, 0x01, 0xcb, 0xc3, 0x17, 0xae, 0xa7, 0x8a, 0xdf, 0x15, 0xe0, 0xda, - 0xf0, 0x8a, 0x45, 0x3f, 0x4a, 0x87, 0x1f, 0x7d, 0xb7, 0xbd, 0x3b, 0xae, 0xd3, 0x61, 0xa6, 0x1f, - 0x38, 0x38, 0xf9, 0xa0, 0xef, 0xcb, 0x46, 0x43, 0x1c, 0x6a, 0x6a, 0xea, 0x9d, 0xb1, 0x51, 0x90, - 0x20, 0xf5, 0x39, 0xdd, 0xc3, 0x88, 0xa3, 0x5a, 0x16, 0x71, 0x68, 0xe5, 0x8f, 0xa0, 0x7f, 0xfe, - 0x4d, 0x3b, 0x0a, 0xfa, 0x19, 0x80, 0x4b, 0x7e, 0x40, 0xbd, 0xad, 0xc3, 0x5b, 0xf7, 0x5e, 0x69, - 0xa8, 0xa9, 0xdb, 0xa4, 0xea, 0xf6, 0xa7, 0xe4, 0xf9, 0x66, 0xe3, 0xe0, 0xb6, 0x0e, 0x78, 0x18, - 0xfa, 0x01, 0xaf, 0x5f, 0xea, 0x75, 0xcb, 0x4b, 0x07, 0x79, 0x28, 0xdc, 0x8f, 0x5d, 0x71, 0xe1, - 0xea, 0xee, 0xa9, 0xa0, 0xa1, 0x47, 0x9c, 0x1d, 0xdf, 0x8e, 0x5c, 0xea, 0x09, 0x4d, 0xf4, 0x35, - 0x38, 0xdf, 0xa4, 0xdc, 0x0e, 0x59, 0xa0, 0x1a, 0xaf, 0x2e, 0xef, 0x4b, 0xa6, 0x2c, 0xe7, 0x77, - 0x52, 0x15, 0xce, 0xda, 0xa1, 0xeb, 0xb0, 0x18, 0x85, 0x8e, 0xa9, 0xe2, 0x79, 0x63, 0x5e, 0xbc, - 0x8b, 0xf7, 0xb0, 0x94, 0x57, 0x36, 0xe0, 0xa4, 0xe4, 0x89, 0xae, 0xc2, 0x62, 0x48, 0x1e, 0xaa, - 0xa8, 0x0b, 0xf5, 0x19, 0x69, 0x82, 0xc9, 0x43, 0x2c, 0x65, 0x95, 0x3f, 0x5d, 0x83, 0x4b, 0x7d, - 0x6b, 0x41, 0x6b, 0xb0, 0xc0, 0x9a, 0x86, 0x03, 0x34, 0x41, 0x0b, 0xb7, 0x76, 0x70, 0x81, 0x35, - 0xd1, 0xeb, 0x70, 0x5a, 0xbf, 0x5e, 0x0c, 0x68, 0x39, 0x99, 0x3b, 0x95, 0x54, 0xde, 0x2c, 0x69, - 0x38, 0x49, 0xc4, 0x98, 0x2b, 0x0e, 0xb4, 0x65, 0x4e, 0x89, 0xe6, 0x40, 0x5b, 0x58, 0xca, 0xfa, - 0x17, 0x3f, 0xf9, 0x94, 0x8b, 0x5f, 0x37, 0xd3, 0xf4, 0x54, 0x7e, 0xae, 0xc8, 0x0c, 0xc9, 0x2f, - 0xc2, 0xe9, 0x96, 0x1f, 0xba, 0x44, 0xa8, 0xdb, 0x23, 0x33, 0xff, 0x7c, 0x5d, 0x49, 0xb1, 0xd1, - 0xca, 0x01, 0x40, 0x30, 0xe1, 0x50, 0x6b, 0x26, 0x3f, 0x00, 0xdc, 0x91, 0x42, 0xac, 0x75, 0xe8, - 0x3e, 0x9c, 0x69, 0xd2, 0x16, 0x89, 0x1c, 0x61, 0xcd, 0xaa, 0x12, 0xda, 0x1e, 0x41, 0x09, 0xd5, - 0xe7, 0xe5, 0x04, 0xb1, 0xa3, 0xe3, 0xe2, 0x18, 0x00, 0xbd, 0x00, 0x67, 0x5c, 0x72, 0xca, 0xdc, - 0xc8, 0xb5, 0xe6, 0xd6, 0xc1, 0x26, 0xd0, 0x66, 0xfb, 0x5a, 0x84, 0x63, 0x9d, 0xec, 0x8c, 0xf4, - 0xd4, 0x76, 0x22, 0xce, 0x3a, 0xd4, 0x28, 0x2d, 0xb8, 0x0e, 0x36, 0x67, 0xd3, 0xce, 0xb8, 0xdb, - 0xa7, 0xc7, 0x03, 0x1e, 0x0a, 0x8c, 0x79, 0xca, 0x79, 0x3e, 0x03, 0xa6, 0x45, 0x38, 0xd6, 0xe5, - 0xc1, 0x8c, 0xfd, 0xc2, 0x30, 0x30, 0xe3, 0x3c, 0xe0, 0x81, 0xbe, 0x08, 0xe7, 0x5c, 0x72, 0xba, - 0x47, 0xbd, 0xb6, 0x38, 0xb6, 0x16, 0xd7, 0xc1, 0x66, 0xb1, 0xbe, 0xd8, 0xeb, 0x96, 0xe7, 0xf6, - 0x63, 0x21, 0x4e, 0xf5, 0xca, 0x98, 0x79, 0xc6, 0xf8, 0xb9, 0x8c, 0x71, 0x2c, 0xc4, 0xa9, 0x5e, - 0x0e, 0x68, 0x01, 0x11, 0xf2, 0x70, 0x59, 0x4b, 0xf9, 0x01, 0xed, 0x50, 0x8b, 0x71, 0xac, 0x47, - 0x9b, 0x70, 0xd6, 0x25, 0xa7, 0x6a, 0x98, 0xb6, 0x96, 0x55, 0xd8, 0x05, 0x39, 0x6b, 0xee, 0x1b, - 0x19, 0x4e, 0xb4, 0xca, 0x92, 0x79, 0xda, 0x72, 0x25, 0x63, 0x69, 0x64, 0x38, 0xd1, 0xca, 0x22, - 0x8e, 0x3c, 0xf6, 0x20, 0xa2, 0xda, 0x18, 0xa9, 0xcc, 0x24, 0x45, 0x7c, 0x37, 0x55, 0xe1, 0xac, - 0x9d, 0x1c, 0x66, 0xdd, 0xc8, 0x11, 0x2c, 0x70, 0xe8, 0x41, 0xcb, 0xba, 0xa4, 0xf2, 0xaf, 0xe6, - 0xa2, 0xfd, 0x44, 0x8a, 0x33, 0x16, 0x88, 0xc2, 0x49, 0xea, 0x45, 0xae, 0x75, 0x59, 0xcd, 0x16, - 0x23, 0x29, 0xc1, 0xe4, 0xe4, 0xec, 0x7a, 0x91, 0x8b, 0x55, 0x78, 0xf4, 0x3a, 0x5c, 0x74, 0xc9, - 0xa9, 0x6c, 0x07, 0x34, 0x14, 0x72, 0xcc, 0x5e, 0x55, 0x8b, 0x5f, 0x91, 0xf7, 0xf9, 0x7e, 0x56, - 0x81, 0xf3, 0x76, 0xca, 0x91, 0x79, 0x19, 0xc7, 0x2b, 0x19, 0xc7, 0xac, 0x02, 0xe7, 0xed, 0x64, - 0xa6, 0x43, 0xfa, 0x20, 0x62, 0x21, 0x6d, 0x5a, 0xff, 0xa7, 0x66, 0x7a, 0x95, 0x69, 0x6c, 0x64, - 0x38, 0xd1, 0xa2, 0x4e, 0xfc, 0xea, 0xb2, 0xd4, 0x31, 0xbc, 0x3b, 0xda, 0x4e, 0x7e, 0x10, 0x6e, - 0x85, 0x21, 0x39, 0xd3, 0x37, 0x4d, 0xf6, 0xbd, 0x85, 0x38, 0x9c, 0x22, 0x8e, 0x73, 0xd0, 0xb2, - 0xae, 0xaa, 0xdc, 0x8f, 0xfa, 0x06, 0x49, 0xba, 0xce, 0x96, 0x04, 0xc1, 0x1a, 0x4b, 0x82, 0xfa, - 0x9e, 0x2c, 0x8d, 0xb5, 0xf1, 0x82, 0x1e, 0x48, 0x10, 0xac, 0xb1, 0xd4, 0x4a, 0xbd, 0xb3, 0x83, - 0x96, 0xf5, 0xff, 0x63, 0x5e, 0xa9, 0x04, 0xc1, 0x1a, 0x0b, 0x31, 0x58, 0xf4, 0x7c, 0x61, 0x5d, - 0x1b, 0xcb, 0xf5, 0xac, 0x2e, 0x9c, 0xdb, 0xbe, 0xc0, 0x12, 0x03, 0xfd, 0x0a, 0x40, 0x18, 0xa4, - 0x25, 0x7a, 0x5d, 0xad, 0xf2, 0xdd, 0xd1, 0x42, 0x56, 0xd3, 0xda, 0xde, 0xf5, 0x44, 0x78, 0x96, - 0x4e, 0xe9, 0x99, 0x33, 0x90, 0x61, 0x81, 0x7e, 0x0f, 0xe0, 0x65, 0xd2, 0xd4, 0x33, 0x3b, 0x71, - 0x32, 0x27, 0xa8, 0xa4, 0x32, 0x72, 0x67, 0xd4, 0x65, 0x5e, 0xf7, 0x7d, 0xa7, 0x6e, 0xf5, 0xba, - 0xe5, 0xcb, 0x5b, 0x17, 0xa0, 0xe2, 0x0b, 0xb9, 0xa0, 0x3f, 0x03, 0xb8, 0x62, 0xba, 0x68, 0x86, - 0x61, 0x59, 0x25, 0x90, 0x8e, 0x3a, 0x81, 0xfd, 0x38, 0x3a, 0x8f, 0x57, 0x4d, 0x1e, 0x57, 0x06, - 0xf4, 0x78, 0x90, 0x1a, 0xfa, 0x1b, 0x80, 0x0b, 0x4d, 0x1a, 0x50, 0xaf, 0x49, 0x3d, 0x5b, 0x72, - 0x5d, 0x1f, 0xc9, 0xa3, 0xac, 0x9f, 0xeb, 0x4e, 0x06, 0x42, 0xd3, 0xac, 0x1a, 0x9a, 0x0b, 0x59, - 0xd5, 0x79, 0xb7, 0x7c, 0x25, 0x75, 0xcd, 0x6a, 0x70, 0x8e, 0x25, 0xfa, 0x35, 0x80, 0x4b, 0xe9, - 0x06, 0xe8, 0x2b, 0x65, 0x63, 0x8c, 0x75, 0xa0, 0xc6, 0xd7, 0xad, 0x3c, 0x20, 0xee, 0x67, 0x80, - 0xfe, 0x02, 0xe4, 0xa4, 0x16, 0x3f, 0xf3, 0xb8, 0x55, 0x51, 0xb9, 0x7c, 0x6f, 0xe4, 0xb9, 0x4c, - 0x10, 0x74, 0x2a, 0x5f, 0x4a, 0x47, 0xc1, 0x44, 0x73, 0xde, 0x2d, 0xaf, 0x66, 0x33, 0x99, 0x28, - 0x70, 0x96, 0x21, 0xfa, 0x29, 0x80, 0x0b, 0x34, 0x9d, 0xb8, 0xb9, 0xf5, 0xfc, 0x48, 0x92, 0x78, - 0xe1, 0x10, 0xaf, 0xff, 0x41, 0xc8, 0xa8, 0x38, 0xce, 0x61, 0xcb, 0x09, 0x92, 0x9e, 0x12, 0x37, - 0x70, 0xa8, 0xf5, 0xb9, 0x11, 0x4f, 0x90, 0xbb, 0x3a, 0x2e, 0x8e, 0x01, 0xd6, 0xe4, 0xcb, 0xa7, - 0xef, 0xe4, 0xa0, 0x65, 0x58, 0x3c, 0xa1, 0x67, 0x7a, 0xb0, 0xc7, 0xf2, 0x27, 0x6a, 0xc2, 0xa9, - 0x0e, 0x71, 0xa2, 0xf8, 0xf1, 0x36, 0xe2, 0xae, 0x8b, 0x75, 0xf0, 0xaf, 0x16, 0xde, 0x00, 0x6b, - 0x8f, 0x00, 0xbc, 0x72, 0xf1, 0x81, 0x7e, 0xa6, 0xb4, 0x7e, 0x0b, 0xe0, 0xca, 0xc0, 0xd9, 0xbd, - 0x80, 0xd1, 0x83, 0x3c, 0xa3, 0xb7, 0x46, 0x7d, 0x08, 0x1b, 0x22, 0x64, 0x5e, 0x5b, 0x4d, 0x1e, - 0x59, 0x7a, 0x3f, 0x07, 0x70, 0xb9, 0xff, 0x38, 0x3c, 0xcb, 0x7c, 0x55, 0x1e, 0x15, 0xe0, 0x95, - 0x8b, 0x07, 0x26, 0x14, 0x26, 0x2f, 0xc3, 0xf1, 0xbc, 0xb0, 0x61, 0xfa, 0xca, 0x4c, 0x1e, 0x95, - 0x1f, 0x00, 0x38, 0x7f, 0x3f, 0xb1, 0x8b, 0xff, 0x87, 0x1f, 0xf9, 0xdb, 0x3e, 0xee, 0x3f, 0xa9, - 0x82, 0xe3, 0x2c, 0x6e, 0xe5, 0xaf, 0x00, 0xae, 0x5e, 0xd8, 0x58, 0xe5, 0x13, 0x94, 0x38, 0x8e, - 0xff, 0x50, 0xff, 0x45, 0x33, 0x9b, 0x3e, 0x41, 0xb7, 0x94, 0x14, 0x1b, 0x6d, 0x26, 0x7b, 0x85, - 0xcf, 0x2a, 0x7b, 0x95, 0xbf, 0x03, 0x78, 0xed, 0xe3, 0x2a, 0xf1, 0x99, 0x6c, 0xe9, 0x26, 0x9c, - 0x35, 0x43, 0xd1, 0x99, 0xda, 0x4e, 0xf3, 0x0e, 0x30, 0x4d, 0xe3, 0x0c, 0x27, 0xda, 0xfa, 0x8d, - 0xc7, 0x4f, 0x4a, 0x13, 0x1f, 0x3e, 0x29, 0x4d, 0x7c, 0xf4, 0xa4, 0x34, 0xf1, 0x83, 0x5e, 0x09, - 0x3c, 0xee, 0x95, 0xc0, 0x87, 0xbd, 0x12, 0xf8, 0xa8, 0x57, 0x02, 0xff, 0xea, 0x95, 0xc0, 0x2f, - 0xff, 0x5d, 0x9a, 0xf8, 0xce, 0x8c, 0x01, 0xff, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0a, 0x6f, - 0x04, 0x49, 0xd3, 0x1e, 0x00, 0x00, + // 1917 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x58, 0xdb, 0x6f, 0x5b, 0x49, + 0x19, 0xcf, 0xd8, 0xb9, 0x4e, 0x92, 0x4d, 0x32, 0x6d, 0xca, 0x69, 0x68, 0xed, 0xd4, 0xcb, 0xae, + 0x02, 0x6c, 0x6d, 0xba, 0x17, 0x76, 0x41, 0xe2, 0x21, 0x6e, 0x02, 0x2a, 0x34, 0x4d, 0x35, 0x69, + 0x8b, 0xc4, 0x2e, 0xec, 0x4e, 0x7c, 0xc6, 0xce, 0x34, 0xe7, 0xcc, 0x39, 0x3d, 0x33, 0xc7, 0x8d, + 0x25, 0x90, 0x40, 0x68, 0x85, 0x84, 0x04, 0x42, 0xd0, 0x17, 0x24, 0x9e, 0x78, 0x44, 0x08, 0x24, + 0xe0, 0x91, 0x3f, 0xa0, 0x8f, 0x2b, 0xf1, 0xb2, 0x4f, 0x16, 0x35, 0xff, 0x02, 0xbc, 0xe4, 0x09, + 0xcd, 0xe5, 0xdc, 0xec, 0x64, 0xb7, 0xd2, 0xda, 0xdb, 0x37, 0x9f, 0xef, 0xf6, 0xfb, 0xcd, 0x37, + 0xdf, 0x7c, 0xf3, 0x8d, 0x61, 0xfb, 0xf8, 0x1d, 0x51, 0x67, 0x41, 0xe3, 0x38, 0x3e, 0xa4, 0x11, + 0xa7, 0x92, 0x8a, 0x46, 0x97, 0x72, 0x37, 0x88, 0x1a, 0x56, 0x41, 0x42, 0x46, 0x4f, 0x24, 0xe5, + 0x82, 0x05, 0x5c, 0x5c, 0x27, 0x21, 0x13, 0x34, 0xea, 0xd2, 0xa8, 0x11, 0x1e, 0x77, 0x94, 0x4e, + 0x14, 0x0d, 0x1a, 0xdd, 0x1b, 0x87, 0x54, 0x92, 0x1b, 0x8d, 0x0e, 0xe5, 0x34, 0x22, 0x92, 0xba, + 0xf5, 0x30, 0x0a, 0x64, 0x80, 0xbe, 0x65, 0xc2, 0xd5, 0x0b, 0xd6, 0xef, 0xa7, 0xe1, 0xea, 0xe1, + 0x71, 0x47, 0xe9, 0x44, 0xd1, 0xa0, 0x6e, 0xc3, 0x6d, 0x5c, 0xef, 0x30, 0x79, 0x14, 0x1f, 0xd6, + 0x5b, 0x81, 0xdf, 0xe8, 0x04, 0x9d, 0xa0, 0xa1, 0xa3, 0x1e, 0xc6, 0x6d, 0xfd, 0xa5, 0x3f, 0xf4, + 0x2f, 0x83, 0xb6, 0xf1, 0x66, 0x46, 0xde, 0x27, 0xad, 0x23, 0xc6, 0x69, 0xd4, 0xcb, 0x18, 0xfb, + 0x54, 0x92, 0x46, 0x77, 0x84, 0xe3, 0x46, 0xe3, 0x3c, 0xaf, 0x28, 0xe6, 0x92, 0xf9, 0x74, 0xc4, + 0xe1, 0xeb, 0x9f, 0xe6, 0x20, 0x5a, 0x47, 0xd4, 0x27, 0x23, 0x7e, 0x6f, 0x9c, 0xe7, 0x17, 0x4b, + 0xe6, 0x35, 0x18, 0x97, 0x42, 0x46, 0xc3, 0x4e, 0xb5, 0x9f, 0x97, 0xa1, 0x73, 0x33, 0x16, 0x32, + 0xf0, 0x31, 0x15, 0x41, 0x1c, 0xb5, 0xe8, 0x0e, 0x6d, 0x33, 0xce, 0x24, 0x0b, 0x38, 0xfa, 0x00, + 0xce, 0xab, 0x55, 0xb9, 0x44, 0x12, 0x07, 0x6c, 0x82, 0xad, 0xc5, 0xd7, 0xbf, 0x56, 0xcf, 0x32, + 0x9e, 0x82, 0x64, 0x69, 0x56, 0xd6, 0xf5, 0xee, 0x8d, 0xfa, 0xfe, 0xe1, 0x43, 0xda, 0x92, 0x7b, + 0x54, 0x92, 0x26, 0x7a, 0xda, 0xaf, 0x4e, 0x0d, 0xfa, 0x55, 0x98, 0xc9, 0x70, 0x1a, 0x15, 0xfd, + 0x04, 0x4e, 0x8b, 0x90, 0xb6, 0x9c, 0x92, 0x8e, 0xfe, 0x6e, 0xfd, 0x33, 0xed, 0x67, 0xfd, 0xbc, + 0x85, 0x1c, 0x84, 0xb4, 0xd5, 0x5c, 0xb2, 0x44, 0xa6, 0xd5, 0x17, 0xd6, 0xb0, 0xe8, 0x43, 0x00, + 0x67, 0x85, 0x24, 0x32, 0x16, 0x4e, 0x59, 0x33, 0xf8, 0xe1, 0xa4, 0x18, 0x68, 0x90, 0xe6, 0x4b, + 0x96, 0xc3, 0xac, 0xf9, 0xc6, 0x16, 0xbc, 0xf6, 0xdf, 0x12, 0xbc, 0x76, 0x9e, 0xeb, 0xcd, 0x80, + 0xbb, 0x66, 0x3b, 0x6e, 0xc1, 0x69, 0xd9, 0x0b, 0xa9, 0xde, 0x8a, 0x85, 0xe6, 0x5b, 0xc9, 0x7a, + 0xee, 0xf5, 0x42, 0x7a, 0xda, 0xaf, 0xbe, 0xf2, 0xa9, 0x01, 0x94, 0x21, 0xd6, 0x21, 0xd0, 0x37, + 0xd2, 0x75, 0x97, 0x74, 0xb0, 0x6b, 0x45, 0x62, 0xa7, 0xfd, 0xea, 0x4a, 0xea, 0x56, 0xe4, 0x8a, + 0xba, 0x10, 0x79, 0x44, 0xc8, 0x7b, 0x11, 0xe1, 0xc2, 0x84, 0x65, 0x3e, 0xb5, 0xe9, 0xfb, 0xca, + 0xf3, 0x95, 0x87, 0xf2, 0x68, 0x6e, 0x58, 0x48, 0x74, 0x7b, 0x24, 0x1a, 0x3e, 0x03, 0x01, 0xbd, + 0x0a, 0x67, 0x23, 0x4a, 0x44, 0xc0, 0x9d, 0x69, 0x4d, 0x39, 0xcd, 0x25, 0xd6, 0x52, 0x6c, 0xb5, + 0xe8, 0xcb, 0x70, 0xce, 0xa7, 0x42, 0x90, 0x0e, 0x75, 0x66, 0xb4, 0xe1, 0x8a, 0x35, 0x9c, 0xdb, + 0x33, 0x62, 0x9c, 0xe8, 0x6b, 0xa7, 0x00, 0x5e, 0x39, 0x2f, 0x6b, 0xb7, 0x99, 0x90, 0xe8, 0xbd, + 0x91, 0x03, 0x50, 0x7f, 0xbe, 0x15, 0x2a, 0x6f, 0x5d, 0xfe, 0xab, 0x16, 0x7c, 0x3e, 0x91, 0xe4, + 0x8a, 0xff, 0xc7, 0x70, 0x86, 0x49, 0xea, 0xab, 0x3d, 0x28, 0x6f, 0x2d, 0xbe, 0xfe, 0xfd, 0x09, + 0xd5, 0x5e, 0x73, 0xd9, 0x72, 0x98, 0xb9, 0xa5, 0xd0, 0xb0, 0x01, 0xad, 0xfd, 0x0f, 0xc0, 0xab, + 0xe7, 0xb9, 0xdc, 0x21, 0x3e, 0x15, 0x2a, 0xe3, 0xa1, 0x17, 0x47, 0xc4, 0xb3, 0x15, 0x97, 0x66, + 0xfc, 0xae, 0x96, 0x62, 0xab, 0x45, 0xaf, 0xc1, 0x79, 0xc1, 0x78, 0x27, 0xf6, 0x48, 0x64, 0xcb, + 0x29, 0x5d, 0xf5, 0x81, 0x95, 0xe3, 0xd4, 0x02, 0xd5, 0x21, 0x14, 0x47, 0x41, 0x24, 0x35, 0x86, + 0x53, 0xde, 0x2c, 0xab, 0xc8, 0xaa, 0x41, 0x1c, 0xa4, 0x52, 0x9c, 0xb3, 0x40, 0x9b, 0x70, 0xfa, + 0x98, 0x71, 0xd7, 0xee, 0x7a, 0x7a, 0x8a, 0xbf, 0xc7, 0xb8, 0x8b, 0xb5, 0x46, 0xe1, 0x7b, 0x4c, + 0x48, 0x25, 0xb1, 0x5b, 0x5e, 0xc8, 0xba, 0xb6, 0x4c, 0x2d, 0x6a, 0x7f, 0x2b, 0x9f, 0xbf, 0xe9, + 0xaa, 0x35, 0xa0, 0x97, 0xe1, 0x4c, 0x27, 0x0a, 0xe2, 0xd0, 0xae, 0x3a, 0xcd, 0xde, 0x77, 0x94, + 0x10, 0x1b, 0x9d, 0xaa, 0xb2, 0x2e, 0x8d, 0xd4, 0x06, 0xd8, 0x25, 0xa7, 0x55, 0xf6, 0xc0, 0x88, + 0x71, 0xa2, 0x47, 0x3f, 0x03, 0x70, 0x86, 0xdb, 0xc5, 0xaa, 0x12, 0x7a, 0x6f, 0x42, 0xfb, 0xac, + 0xd3, 0x95, 0xd1, 0x35, 0x99, 0x34, 0xc8, 0xe8, 0x4d, 0x38, 0x23, 0x5a, 0x41, 0x48, 0x6d, 0x16, + 0x2b, 0x89, 0xd1, 0x81, 0x12, 0x9e, 0xf6, 0xab, 0xcb, 0x49, 0x38, 0x2d, 0xc0, 0xc6, 0x18, 0xfd, + 0x02, 0x40, 0xd8, 0x25, 0x1e, 0x73, 0x89, 0x8a, 0xaf, 0x73, 0x3b, 0xee, 0x32, 0x7d, 0x90, 0x86, + 0x37, 0x45, 0x90, 0x7d, 0xe3, 0x1c, 0x74, 0xed, 0x5f, 0x25, 0x58, 0xf9, 0xe4, 0xde, 0x8a, 0x9e, + 0x00, 0x08, 0x5b, 0x49, 0xcf, 0x12, 0x0e, 0xd0, 0x67, 0xea, 0x83, 0x09, 0xe5, 0x3a, 0x6d, 0x8e, + 0xd9, 0xfd, 0x96, 0x8a, 0x04, 0xce, 0xf1, 0x40, 0xbf, 0x07, 0x70, 0x99, 0xb4, 0x5a, 0x34, 0x94, + 0xd4, 0x35, 0x25, 0x5f, 0xfa, 0x1c, 0xaa, 0x60, 0xdd, 0xb2, 0x5a, 0xde, 0xce, 0x43, 0xe3, 0x22, + 0x93, 0xda, 0x9f, 0xc0, 0xf0, 0xe5, 0x9f, 0xa5, 0x1f, 0xfd, 0x0a, 0xc0, 0x95, 0x20, 0xa4, 0x7c, + 0xfb, 0xee, 0xad, 0x07, 0x6f, 0x1c, 0xe8, 0x91, 0xc3, 0xf6, 0xc0, 0x3b, 0x9f, 0x91, 0xfa, 0x77, + 0x0f, 0xf6, 0xef, 0x98, 0x80, 0x77, 0xa3, 0x20, 0x14, 0xcd, 0x0b, 0x83, 0x7e, 0x75, 0x65, 0xbf, + 0x08, 0x85, 0x87, 0xb1, 0x6b, 0x3e, 0x5c, 0xdf, 0x3d, 0x91, 0x34, 0xe2, 0xc4, 0xdb, 0x09, 0x5a, + 0xb1, 0x4f, 0xb9, 0x34, 0x44, 0xdf, 0x82, 0x8b, 0x2e, 0x15, 0xad, 0x88, 0x85, 0xba, 0x4a, 0xcd, + 0xa9, 0xbd, 0x60, 0x13, 0xb0, 0xb8, 0x93, 0xa9, 0x70, 0xde, 0x0e, 0x5d, 0x85, 0xe5, 0x38, 0xf2, + 0xec, 0xe9, 0x5d, 0xb4, 0xe6, 0xe5, 0xfb, 0xf8, 0x36, 0x56, 0xf2, 0xda, 0x35, 0x38, 0xad, 0x78, + 0xa2, 0xcb, 0xb0, 0x1c, 0x91, 0xc7, 0x3a, 0xea, 0x52, 0x73, 0x4e, 0x99, 0x60, 0xf2, 0x18, 0x2b, + 0x59, 0xed, 0xcf, 0x57, 0xe0, 0xca, 0xd0, 0x5a, 0xd0, 0x06, 0x2c, 0x31, 0xd7, 0x72, 0x80, 0x36, + 0x68, 0xe9, 0xd6, 0x0e, 0x2e, 0x31, 0x17, 0xbd, 0x0d, 0x67, 0xcd, 0xe8, 0x66, 0x41, 0xab, 0xe9, + 0xa5, 0xab, 0xa5, 0xea, 0x18, 0x66, 0xe1, 0x14, 0x11, 0x6b, 0xae, 0x39, 0xd0, 0xb6, 0x6e, 0x1f, + 0x0b, 0x96, 0x03, 0x6d, 0x63, 0x25, 0x1b, 0x5e, 0xfc, 0xf4, 0x73, 0x2e, 0x7e, 0xd3, 0x8e, 0x12, + 0x33, 0xc5, 0xa6, 0x9a, 0x9b, 0x10, 0x5e, 0x85, 0xb3, 0xed, 0x20, 0xf2, 0x89, 0x74, 0x66, 0x8b, + 0xcd, 0xff, 0xdb, 0x5a, 0x8a, 0xad, 0x56, 0x75, 0x4b, 0xc9, 0xa4, 0x47, 0x9d, 0xb9, 0x62, 0xb7, + 0xbc, 0xa7, 0x84, 0xd8, 0xe8, 0xd0, 0x43, 0x38, 0xe7, 0xd2, 0x36, 0x89, 0x3d, 0xe9, 0xcc, 0xeb, + 0x12, 0xba, 0x39, 0x86, 0x12, 0x6a, 0x2e, 0xaa, 0x76, 0xbb, 0x63, 0xe2, 0xe2, 0x04, 0x00, 0xbd, + 0x02, 0xe7, 0x7c, 0x72, 0xc2, 0xfc, 0xd8, 0x77, 0x16, 0x36, 0xc1, 0x16, 0x30, 0x66, 0x7b, 0x46, + 0x84, 0x13, 0x1d, 0xda, 0x81, 0xab, 0xf4, 0xa4, 0xe5, 0xc5, 0x82, 0x75, 0xa9, 0x55, 0x3a, 0x70, + 0x13, 0x6c, 0xcd, 0x37, 0x1d, 0xbb, 0x84, 0xd5, 0xdd, 0x21, 0x3d, 0x1e, 0xf1, 0xd0, 0x60, 0x8c, + 0x6b, 0xe7, 0xc5, 0x1c, 0x98, 0x11, 0xe1, 0x44, 0x57, 0x04, 0xb3, 0xf6, 0x4b, 0xe7, 0x81, 0x59, + 0xe7, 0x11, 0x0f, 0xf4, 0x55, 0xb8, 0xe0, 0x93, 0x93, 0xdb, 0x94, 0x77, 0xe4, 0x91, 0xb3, 0xbc, + 0x09, 0xb6, 0xca, 0xcd, 0xe5, 0x41, 0xbf, 0xba, 0xb0, 0x97, 0x08, 0x71, 0xa6, 0xd7, 0xc6, 0x8c, + 0x5b, 0xe3, 0x97, 0x72, 0xc6, 0x89, 0x10, 0x67, 0x7a, 0x75, 0x9b, 0x85, 0x44, 0xaa, 0xc3, 0xe5, + 0xac, 0x14, 0x6f, 0xb3, 0xbb, 0x46, 0x8c, 0x13, 0x3d, 0xda, 0x82, 0xf3, 0x3e, 0x39, 0xd1, 0x93, + 0x84, 0xb3, 0xaa, 0xc3, 0x2e, 0xa9, 0x8b, 0x76, 0xcf, 0xca, 0x70, 0xaa, 0xd5, 0x96, 0x8c, 0x1b, + 0xcb, 0xb5, 0x9c, 0xa5, 0x95, 0xe1, 0x54, 0xab, 0x8a, 0x38, 0xe6, 0xec, 0x51, 0x4c, 0x8d, 0x31, + 0xd2, 0x99, 0x49, 0x8b, 0xf8, 0x7e, 0xa6, 0xc2, 0x79, 0x3b, 0x35, 0x49, 0xf8, 0xb1, 0x27, 0x59, + 0xe8, 0xd1, 0xfd, 0xb6, 0x73, 0x41, 0xe7, 0x5f, 0x5f, 0x22, 0x7b, 0xa9, 0x14, 0xe7, 0x2c, 0x10, + 0x85, 0xd3, 0x94, 0xc7, 0xbe, 0x73, 0x51, 0x5f, 0x0d, 0x63, 0x29, 0xc1, 0xf4, 0xe4, 0xec, 0xf2, + 0xd8, 0xc7, 0x3a, 0x3c, 0x7a, 0x1b, 0x2e, 0xfb, 0xe4, 0x44, 0xb5, 0x03, 0x1a, 0x49, 0x46, 0x85, + 0xb3, 0xae, 0x17, 0xbf, 0xa6, 0xda, 0xf1, 0x5e, 0x5e, 0x81, 0x8b, 0x76, 0xda, 0x91, 0xf1, 0x9c, + 0xe3, 0xa5, 0x9c, 0x63, 0x5e, 0x81, 0x8b, 0x76, 0x2a, 0xd3, 0x11, 0x7d, 0x14, 0xb3, 0x88, 0xba, + 0xce, 0x17, 0xf4, 0x40, 0xa5, 0x33, 0x8d, 0xad, 0x0c, 0xa7, 0x5a, 0xd4, 0x4d, 0x46, 0x4e, 0x47, + 0x1f, 0xc3, 0xfb, 0xe3, 0xed, 0xe4, 0xfb, 0xd1, 0x76, 0x14, 0x91, 0x5e, 0x73, 0x61, 0x78, 0xd8, + 0x44, 0x02, 0xce, 0x10, 0xcf, 0xdb, 0x6f, 0x3b, 0x97, 0x75, 0xee, 0xc7, 0x7d, 0x83, 0xa4, 0x5d, + 0x67, 0x5b, 0x81, 0x60, 0x83, 0xa5, 0x40, 0x03, 0xae, 0x4a, 0x63, 0x63, 0xb2, 0xa0, 0xfb, 0x0a, + 0x04, 0x1b, 0x2c, 0xbd, 0x52, 0xde, 0xdb, 0x6f, 0x3b, 0x5f, 0x9c, 0xf0, 0x4a, 0x15, 0x08, 0x36, + 0x58, 0x88, 0xc1, 0x32, 0x0f, 0xa4, 0x73, 0x65, 0x22, 0xd7, 0xb3, 0xbe, 0x70, 0xee, 0x04, 0x12, + 0x2b, 0x0c, 0xf4, 0x5b, 0x00, 0x61, 0x98, 0x95, 0xe8, 0x55, 0xbd, 0xca, 0x1f, 0x8d, 0x17, 0xb2, + 0x9e, 0xd5, 0xf6, 0x2e, 0x97, 0x51, 0x2f, 0x1b, 0xb2, 0x72, 0x67, 0x20, 0xc7, 0x02, 0xfd, 0x11, + 0xc0, 0x8b, 0xc4, 0x35, 0x23, 0x17, 0xf1, 0x72, 0x27, 0xa8, 0xa2, 0x33, 0x72, 0x6f, 0xdc, 0x65, + 0xde, 0x0c, 0x02, 0xaf, 0xe9, 0x0c, 0xfa, 0xd5, 0x8b, 0xdb, 0x67, 0xa0, 0xe2, 0x33, 0xb9, 0xa0, + 0xbf, 0x00, 0xb8, 0x66, 0xbb, 0x68, 0x8e, 0x61, 0x55, 0x27, 0x90, 0x8e, 0x3b, 0x81, 0xc3, 0x38, + 0x26, 0x8f, 0x97, 0x6d, 0x1e, 0xd7, 0x46, 0xf4, 0x78, 0x94, 0x1a, 0xfa, 0x07, 0x80, 0x4b, 0x2e, + 0x0d, 0x29, 0x77, 0x29, 0x6f, 0x29, 0xae, 0x9b, 0x63, 0x99, 0xa9, 0x87, 0xb9, 0xee, 0xe4, 0x20, + 0x0c, 0xcd, 0xba, 0xa5, 0xb9, 0x94, 0x57, 0x9d, 0xf6, 0xab, 0x97, 0x32, 0xd7, 0xbc, 0x06, 0x17, + 0x58, 0xa2, 0xdf, 0x01, 0xb8, 0x92, 0x6d, 0x80, 0xb9, 0x52, 0xae, 0x4d, 0xb0, 0x0e, 0xf4, 0xf8, + 0xba, 0x5d, 0x04, 0xc4, 0xc3, 0x0c, 0xd0, 0x5f, 0x81, 0x9a, 0xd4, 0x92, 0x29, 0x5d, 0x38, 0x35, + 0x9d, 0xcb, 0xf7, 0xc7, 0x9e, 0xcb, 0x14, 0xc1, 0xa4, 0xf2, 0xb5, 0x6c, 0x14, 0x4c, 0x35, 0xa7, + 0xfd, 0xea, 0x7a, 0x3e, 0x93, 0xa9, 0x02, 0xe7, 0x19, 0xa2, 0x5f, 0x02, 0xb8, 0x44, 0xb3, 0x89, + 0x5b, 0x38, 0x2f, 0x8f, 0x25, 0x89, 0x67, 0x0e, 0xf1, 0xcd, 0x55, 0xb5, 0xdd, 0x39, 0x95, 0xc0, + 0x05, 0x6c, 0x35, 0x41, 0xd2, 0x13, 0xe2, 0x87, 0x1e, 0x75, 0xbe, 0x34, 0xe6, 0x09, 0x72, 0xd7, + 0xc4, 0xc5, 0x09, 0xc0, 0x86, 0x7a, 0xf9, 0x0c, 0x9d, 0x1c, 0xb4, 0x0a, 0xcb, 0xc7, 0xb4, 0x67, + 0x06, 0x7b, 0xac, 0x7e, 0x22, 0x17, 0xce, 0x74, 0x89, 0x17, 0x53, 0xfb, 0x9e, 0x1b, 0x73, 0xd7, + 0xc5, 0x26, 0xf8, 0x37, 0x4b, 0xef, 0x80, 0x8d, 0x27, 0x00, 0x5e, 0x3a, 0xfb, 0x40, 0xbf, 0x50, + 0x5a, 0x7f, 0x00, 0x70, 0x6d, 0xe4, 0xec, 0x9e, 0xc1, 0xe8, 0x51, 0x91, 0xd1, 0xbb, 0xe3, 0x3e, + 0x84, 0x07, 0x32, 0x62, 0xbc, 0xa3, 0x27, 0x8f, 0x3c, 0xbd, 0x5f, 0x03, 0xb8, 0x3a, 0x7c, 0x1c, + 0x5e, 0x64, 0xbe, 0x6a, 0x4f, 0x4a, 0xf0, 0xd2, 0xd9, 0x03, 0x13, 0x8a, 0xd2, 0x97, 0xe1, 0x64, + 0x5e, 0xd8, 0x30, 0x7b, 0x65, 0xa6, 0x8f, 0xca, 0x0f, 0x01, 0x5c, 0x7c, 0x98, 0xda, 0x25, 0x7f, + 0x42, 0x8e, 0xfd, 0x6d, 0x9f, 0xf4, 0x9f, 0x4c, 0x21, 0x70, 0x1e, 0xb7, 0xf6, 0x77, 0x00, 0xd7, + 0xcf, 0x6c, 0xac, 0xea, 0x09, 0x4a, 0x3c, 0x2f, 0x78, 0x2c, 0x74, 0x56, 0xe6, 0xb3, 0x27, 0xe8, + 0xb6, 0x96, 0x62, 0xab, 0xcd, 0x65, 0xaf, 0xf4, 0x79, 0x65, 0xaf, 0xf6, 0x4f, 0x00, 0xaf, 0x7c, + 0x52, 0x25, 0xbe, 0x90, 0x2d, 0xdd, 0x82, 0xf3, 0x76, 0x28, 0xea, 0xe9, 0xed, 0xb4, 0xef, 0x00, + 0xdb, 0x34, 0x7a, 0x38, 0xd5, 0x36, 0xaf, 0x3f, 0x7d, 0x56, 0x99, 0xfa, 0xe8, 0x59, 0x65, 0xea, + 0xe3, 0x67, 0x95, 0xa9, 0x9f, 0x0e, 0x2a, 0xe0, 0xe9, 0xa0, 0x02, 0x3e, 0x1a, 0x54, 0xc0, 0xc7, + 0x83, 0x0a, 0xf8, 0xf7, 0xa0, 0x02, 0x7e, 0xf3, 0x9f, 0xca, 0xd4, 0x0f, 0xe6, 0x2c, 0xf8, 0xff, + 0x03, 0x00, 0x00, 0xff, 0xff, 0x73, 0x96, 0x20, 0xc5, 0xd0, 0x1b, 0x00, 0x00, } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto index 46cfd1ca7..7cfc44c4c 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/generated.proto @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -88,10 +88,6 @@ message CustomResourceDefinitionNames { // ListKind is the serialized kind of the list for this resource. Defaults to <kind>List. optional string listKind = 5; - - // Categories is a list of grouped resources custom resources belong to (e.g. 'all') - // +optional - repeated string categories = 6; } // CustomResourceDefinitionSpec describes how a user wants their resource to appear @@ -111,12 +107,6 @@ message CustomResourceDefinitionSpec { // Validation describes the validation methods for CustomResources // +optional optional CustomResourceValidation validation = 5; - - // Subresources describes the subresources for CustomResources - // This field is alpha-level and should only be sent to servers that enable - // subresources via the CustomResourceSubresources feature gate. - // +optional - optional CustomResourceSubresources subresources = 6; } // CustomResourceDefinitionStatus indicates the state of the CustomResourceDefinition @@ -129,48 +119,6 @@ message CustomResourceDefinitionStatus { optional CustomResourceDefinitionNames acceptedNames = 2; } -// CustomResourceSubresourceScale defines how to serve the scale subresource for CustomResources. -message CustomResourceSubresourceScale { - // SpecReplicasPath defines the JSON path inside of a CustomResource that corresponds to Scale.Spec.Replicas. - // Only JSON paths without the array notation are allowed. - // Must be a JSON Path under .spec. - // If there is no value under the given path in the CustomResource, the /scale subresource will return an error on GET. - optional string specReplicasPath = 1; - - // StatusReplicasPath defines the JSON path inside of a CustomResource that corresponds to Scale.Status.Replicas. - // Only JSON paths without the array notation are allowed. - // Must be a JSON Path under .status. - // If there is no value under the given path in the CustomResource, the status replica value in the /scale subresource - // will default to 0. - optional string statusReplicasPath = 2; - - // LabelSelectorPath defines the JSON path inside of a CustomResource that corresponds to Scale.Status.Selector. - // Only JSON paths without the array notation are allowed. - // Must be a JSON Path under .status. - // Must be set to work with HPA. - // If there is no value under the given path in the CustomResource, the status label selector value in the /scale - // subresource will default to the empty string. - // +optional - optional string labelSelectorPath = 3; -} - -// CustomResourceSubresourceStatus defines how to serve the status subresource for CustomResources. -// Status is represented by the `.status` JSON path inside of a CustomResource. When set, -// * exposes a /status subresource for the custom resource -// * PUT requests to the /status subresource take a custom resource object, and ignore changes to anything except the status stanza -// * PUT/POST/PATCH requests to the custom resource ignore changes to the status stanza -message CustomResourceSubresourceStatus { -} - -// CustomResourceSubresources defines the status and scale subresources for CustomResources. -message CustomResourceSubresources { - // Status denotes the status subresource for CustomResources - optional CustomResourceSubresourceStatus status = 1; - - // Scale denotes the scale subresource for CustomResources - optional CustomResourceSubresourceScale scale = 2; -} - // CustomResourceValidation is a list of validation methods for CustomResources. message CustomResourceValidation { // OpenAPIV3Schema is the OpenAPI v3 schema to be validated against. diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types.go index 3a4da9aea..9ac37efe0 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/types.go @@ -16,9 +16,7 @@ limitations under the License. package v1beta1 -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) +import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" // CustomResourceDefinitionSpec describes how a user wants their resource to appear type CustomResourceDefinitionSpec struct { @@ -33,11 +31,6 @@ type CustomResourceDefinitionSpec struct { // Validation describes the validation methods for CustomResources // +optional Validation *CustomResourceValidation `json:"validation,omitempty" protobuf:"bytes,5,opt,name=validation"` - // Subresources describes the subresources for CustomResources - // This field is alpha-level and should only be sent to servers that enable - // subresources via the CustomResourceSubresources feature gate. - // +optional - Subresources *CustomResourceSubresources `json:"subresources,omitempty" protobuf:"bytes,6,opt,name=subresources"` } // CustomResourceDefinitionNames indicates the names to serve this CustomResourceDefinition @@ -53,9 +46,6 @@ type CustomResourceDefinitionNames struct { Kind string `json:"kind" protobuf:"bytes,4,opt,name=kind"` // ListKind is the serialized kind of the list for this resource. Defaults to <kind>List. ListKind string `json:"listKind,omitempty" protobuf:"bytes,5,opt,name=listKind"` - // Categories is a list of grouped resources custom resources belong to (e.g. 'all') - // +optional - Categories []string `json:"categories,omitempty" protobuf:"bytes,6,rep,name=categories"` } // ResourceScope is an enum defining the different scopes available to a custom resource @@ -157,41 +147,3 @@ type CustomResourceValidation struct { // OpenAPIV3Schema is the OpenAPI v3 schema to be validated against. OpenAPIV3Schema *JSONSchemaProps `json:"openAPIV3Schema,omitempty" protobuf:"bytes,1,opt,name=openAPIV3Schema"` } - -// CustomResourceSubresources defines the status and scale subresources for CustomResources. -type CustomResourceSubresources struct { - // Status denotes the status subresource for CustomResources - Status *CustomResourceSubresourceStatus `json:"status,omitempty" protobuf:"bytes,1,opt,name=status"` - // Scale denotes the scale subresource for CustomResources - Scale *CustomResourceSubresourceScale `json:"scale,omitempty" protobuf:"bytes,2,opt,name=scale"` -} - -// CustomResourceSubresourceStatus defines how to serve the status subresource for CustomResources. -// Status is represented by the `.status` JSON path inside of a CustomResource. When set, -// * exposes a /status subresource for the custom resource -// * PUT requests to the /status subresource take a custom resource object, and ignore changes to anything except the status stanza -// * PUT/POST/PATCH requests to the custom resource ignore changes to the status stanza -type CustomResourceSubresourceStatus struct{} - -// CustomResourceSubresourceScale defines how to serve the scale subresource for CustomResources. -type CustomResourceSubresourceScale struct { - // SpecReplicasPath defines the JSON path inside of a CustomResource that corresponds to Scale.Spec.Replicas. - // Only JSON paths without the array notation are allowed. - // Must be a JSON Path under .spec. - // If there is no value under the given path in the CustomResource, the /scale subresource will return an error on GET. - SpecReplicasPath string `json:"specReplicasPath" protobuf:"bytes,1,name=specReplicasPath"` - // StatusReplicasPath defines the JSON path inside of a CustomResource that corresponds to Scale.Status.Replicas. - // Only JSON paths without the array notation are allowed. - // Must be a JSON Path under .status. - // If there is no value under the given path in the CustomResource, the status replica value in the /scale subresource - // will default to 0. - StatusReplicasPath string `json:"statusReplicasPath" protobuf:"bytes,2,opt,name=statusReplicasPath"` - // LabelSelectorPath defines the JSON path inside of a CustomResource that corresponds to Scale.Status.Selector. - // Only JSON paths without the array notation are allowed. - // Must be a JSON Path under .status. - // Must be set to work with HPA. - // If there is no value under the given path in the CustomResource, the status label selector value in the /scale - // subresource will default to the empty string. - // +optional - LabelSelectorPath *string `json:"labelSelectorPath,omitempty" protobuf:"bytes,3,opt,name=labelSelectorPath"` -} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.conversion.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.conversion.go index 6cd42fe5b..26fcb6cc0 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.conversion.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.conversion.go @@ -1,7 +1,7 @@ // +build !ignore_autogenerated /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,16 +16,15 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by conversion-gen. DO NOT EDIT. +// This file was autogenerated by conversion-gen. Do not edit it manually! package v1beta1 import ( - unsafe "unsafe" - apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" conversion "k8s.io/apimachinery/pkg/conversion" runtime "k8s.io/apimachinery/pkg/runtime" + unsafe "unsafe" ) func init() { @@ -48,12 +47,6 @@ func RegisterConversions(scheme *runtime.Scheme) error { Convert_apiextensions_CustomResourceDefinitionSpec_To_v1beta1_CustomResourceDefinitionSpec, Convert_v1beta1_CustomResourceDefinitionStatus_To_apiextensions_CustomResourceDefinitionStatus, Convert_apiextensions_CustomResourceDefinitionStatus_To_v1beta1_CustomResourceDefinitionStatus, - Convert_v1beta1_CustomResourceSubresourceScale_To_apiextensions_CustomResourceSubresourceScale, - Convert_apiextensions_CustomResourceSubresourceScale_To_v1beta1_CustomResourceSubresourceScale, - Convert_v1beta1_CustomResourceSubresourceStatus_To_apiextensions_CustomResourceSubresourceStatus, - Convert_apiextensions_CustomResourceSubresourceStatus_To_v1beta1_CustomResourceSubresourceStatus, - Convert_v1beta1_CustomResourceSubresources_To_apiextensions_CustomResourceSubresources, - Convert_apiextensions_CustomResourceSubresources_To_v1beta1_CustomResourceSubresources, Convert_v1beta1_CustomResourceValidation_To_apiextensions_CustomResourceValidation, Convert_apiextensions_CustomResourceValidation_To_v1beta1_CustomResourceValidation, Convert_v1beta1_ExternalDocumentation_To_apiextensions_ExternalDocumentation, @@ -179,7 +172,6 @@ func autoConvert_v1beta1_CustomResourceDefinitionNames_To_apiextensions_CustomRe out.ShortNames = *(*[]string)(unsafe.Pointer(&in.ShortNames)) out.Kind = in.Kind out.ListKind = in.ListKind - out.Categories = *(*[]string)(unsafe.Pointer(&in.Categories)) return nil } @@ -194,7 +186,6 @@ func autoConvert_apiextensions_CustomResourceDefinitionNames_To_v1beta1_CustomRe out.ShortNames = *(*[]string)(unsafe.Pointer(&in.ShortNames)) out.Kind = in.Kind out.ListKind = in.ListKind - out.Categories = *(*[]string)(unsafe.Pointer(&in.Categories)) return nil } @@ -219,7 +210,6 @@ func autoConvert_v1beta1_CustomResourceDefinitionSpec_To_apiextensions_CustomRes } else { out.Validation = nil } - out.Subresources = (*apiextensions.CustomResourceSubresources)(unsafe.Pointer(in.Subresources)) return nil } @@ -244,7 +234,6 @@ func autoConvert_apiextensions_CustomResourceDefinitionSpec_To_v1beta1_CustomRes } else { out.Validation = nil } - out.Subresources = (*CustomResourceSubresources)(unsafe.Pointer(in.Subresources)) return nil } @@ -279,70 +268,6 @@ func Convert_apiextensions_CustomResourceDefinitionStatus_To_v1beta1_CustomResou return autoConvert_apiextensions_CustomResourceDefinitionStatus_To_v1beta1_CustomResourceDefinitionStatus(in, out, s) } -func autoConvert_v1beta1_CustomResourceSubresourceScale_To_apiextensions_CustomResourceSubresourceScale(in *CustomResourceSubresourceScale, out *apiextensions.CustomResourceSubresourceScale, s conversion.Scope) error { - out.SpecReplicasPath = in.SpecReplicasPath - out.StatusReplicasPath = in.StatusReplicasPath - out.LabelSelectorPath = (*string)(unsafe.Pointer(in.LabelSelectorPath)) - return nil -} - -// Convert_v1beta1_CustomResourceSubresourceScale_To_apiextensions_CustomResourceSubresourceScale is an autogenerated conversion function. -func Convert_v1beta1_CustomResourceSubresourceScale_To_apiextensions_CustomResourceSubresourceScale(in *CustomResourceSubresourceScale, out *apiextensions.CustomResourceSubresourceScale, s conversion.Scope) error { - return autoConvert_v1beta1_CustomResourceSubresourceScale_To_apiextensions_CustomResourceSubresourceScale(in, out, s) -} - -func autoConvert_apiextensions_CustomResourceSubresourceScale_To_v1beta1_CustomResourceSubresourceScale(in *apiextensions.CustomResourceSubresourceScale, out *CustomResourceSubresourceScale, s conversion.Scope) error { - out.SpecReplicasPath = in.SpecReplicasPath - out.StatusReplicasPath = in.StatusReplicasPath - out.LabelSelectorPath = (*string)(unsafe.Pointer(in.LabelSelectorPath)) - return nil -} - -// Convert_apiextensions_CustomResourceSubresourceScale_To_v1beta1_CustomResourceSubresourceScale is an autogenerated conversion function. -func Convert_apiextensions_CustomResourceSubresourceScale_To_v1beta1_CustomResourceSubresourceScale(in *apiextensions.CustomResourceSubresourceScale, out *CustomResourceSubresourceScale, s conversion.Scope) error { - return autoConvert_apiextensions_CustomResourceSubresourceScale_To_v1beta1_CustomResourceSubresourceScale(in, out, s) -} - -func autoConvert_v1beta1_CustomResourceSubresourceStatus_To_apiextensions_CustomResourceSubresourceStatus(in *CustomResourceSubresourceStatus, out *apiextensions.CustomResourceSubresourceStatus, s conversion.Scope) error { - return nil -} - -// Convert_v1beta1_CustomResourceSubresourceStatus_To_apiextensions_CustomResourceSubresourceStatus is an autogenerated conversion function. -func Convert_v1beta1_CustomResourceSubresourceStatus_To_apiextensions_CustomResourceSubresourceStatus(in *CustomResourceSubresourceStatus, out *apiextensions.CustomResourceSubresourceStatus, s conversion.Scope) error { - return autoConvert_v1beta1_CustomResourceSubresourceStatus_To_apiextensions_CustomResourceSubresourceStatus(in, out, s) -} - -func autoConvert_apiextensions_CustomResourceSubresourceStatus_To_v1beta1_CustomResourceSubresourceStatus(in *apiextensions.CustomResourceSubresourceStatus, out *CustomResourceSubresourceStatus, s conversion.Scope) error { - return nil -} - -// Convert_apiextensions_CustomResourceSubresourceStatus_To_v1beta1_CustomResourceSubresourceStatus is an autogenerated conversion function. -func Convert_apiextensions_CustomResourceSubresourceStatus_To_v1beta1_CustomResourceSubresourceStatus(in *apiextensions.CustomResourceSubresourceStatus, out *CustomResourceSubresourceStatus, s conversion.Scope) error { - return autoConvert_apiextensions_CustomResourceSubresourceStatus_To_v1beta1_CustomResourceSubresourceStatus(in, out, s) -} - -func autoConvert_v1beta1_CustomResourceSubresources_To_apiextensions_CustomResourceSubresources(in *CustomResourceSubresources, out *apiextensions.CustomResourceSubresources, s conversion.Scope) error { - out.Status = (*apiextensions.CustomResourceSubresourceStatus)(unsafe.Pointer(in.Status)) - out.Scale = (*apiextensions.CustomResourceSubresourceScale)(unsafe.Pointer(in.Scale)) - return nil -} - -// Convert_v1beta1_CustomResourceSubresources_To_apiextensions_CustomResourceSubresources is an autogenerated conversion function. -func Convert_v1beta1_CustomResourceSubresources_To_apiextensions_CustomResourceSubresources(in *CustomResourceSubresources, out *apiextensions.CustomResourceSubresources, s conversion.Scope) error { - return autoConvert_v1beta1_CustomResourceSubresources_To_apiextensions_CustomResourceSubresources(in, out, s) -} - -func autoConvert_apiextensions_CustomResourceSubresources_To_v1beta1_CustomResourceSubresources(in *apiextensions.CustomResourceSubresources, out *CustomResourceSubresources, s conversion.Scope) error { - out.Status = (*CustomResourceSubresourceStatus)(unsafe.Pointer(in.Status)) - out.Scale = (*CustomResourceSubresourceScale)(unsafe.Pointer(in.Scale)) - return nil -} - -// Convert_apiextensions_CustomResourceSubresources_To_v1beta1_CustomResourceSubresources is an autogenerated conversion function. -func Convert_apiextensions_CustomResourceSubresources_To_v1beta1_CustomResourceSubresources(in *apiextensions.CustomResourceSubresources, out *CustomResourceSubresources, s conversion.Scope) error { - return autoConvert_apiextensions_CustomResourceSubresources_To_v1beta1_CustomResourceSubresources(in, out, s) -} - func autoConvert_v1beta1_CustomResourceValidation_To_apiextensions_CustomResourceValidation(in *CustomResourceValidation, out *apiextensions.CustomResourceValidation, s conversion.Scope) error { if in.OpenAPIV3Schema != nil { in, out := &in.OpenAPIV3Schema, &out.OpenAPIV3Schema diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.deepcopy.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.deepcopy.go index 35c3a0b75..697f87417 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.deepcopy.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ // +build !ignore_autogenerated /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by deepcopy-gen. DO NOT EDIT. +// This file was autogenerated by deepcopy-gen. Do not edit it manually! package v1beta1 @@ -48,8 +48,9 @@ func (in *CustomResourceDefinition) DeepCopy() *CustomResourceDefinition { func (in *CustomResourceDefinition) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c + } else { + return nil } - return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -98,8 +99,9 @@ func (in *CustomResourceDefinitionList) DeepCopy() *CustomResourceDefinitionList func (in *CustomResourceDefinitionList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c + } else { + return nil } - return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -110,11 +112,6 @@ func (in *CustomResourceDefinitionNames) DeepCopyInto(out *CustomResourceDefinit *out = make([]string, len(*in)) copy(*out, *in) } - if in.Categories != nil { - in, out := &in.Categories, &out.Categories - *out = make([]string, len(*in)) - copy(*out, *in) - } return } @@ -141,15 +138,6 @@ func (in *CustomResourceDefinitionSpec) DeepCopyInto(out *CustomResourceDefiniti (*in).DeepCopyInto(*out) } } - if in.Subresources != nil { - in, out := &in.Subresources, &out.Subresources - if *in == nil { - *out = nil - } else { - *out = new(CustomResourceSubresources) - (*in).DeepCopyInto(*out) - } - } return } @@ -187,81 +175,6 @@ func (in *CustomResourceDefinitionStatus) DeepCopy() *CustomResourceDefinitionSt return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CustomResourceSubresourceScale) DeepCopyInto(out *CustomResourceSubresourceScale) { - *out = *in - if in.LabelSelectorPath != nil { - in, out := &in.LabelSelectorPath, &out.LabelSelectorPath - if *in == nil { - *out = nil - } else { - *out = new(string) - **out = **in - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceSubresourceScale. -func (in *CustomResourceSubresourceScale) DeepCopy() *CustomResourceSubresourceScale { - if in == nil { - return nil - } - out := new(CustomResourceSubresourceScale) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CustomResourceSubresourceStatus) DeepCopyInto(out *CustomResourceSubresourceStatus) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceSubresourceStatus. -func (in *CustomResourceSubresourceStatus) DeepCopy() *CustomResourceSubresourceStatus { - if in == nil { - return nil - } - out := new(CustomResourceSubresourceStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CustomResourceSubresources) DeepCopyInto(out *CustomResourceSubresources) { - *out = *in - if in.Status != nil { - in, out := &in.Status, &out.Status - if *in == nil { - *out = nil - } else { - *out = new(CustomResourceSubresourceStatus) - **out = **in - } - } - if in.Scale != nil { - in, out := &in.Scale, &out.Scale - if *in == nil { - *out = nil - } else { - *out = new(CustomResourceSubresourceScale) - (*in).DeepCopyInto(*out) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceSubresources. -func (in *CustomResourceSubresources) DeepCopy() *CustomResourceSubresources { - if in == nil { - return nil - } - out := new(CustomResourceSubresources) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CustomResourceValidation) DeepCopyInto(out *CustomResourceValidation) { *out = *in @@ -270,7 +183,8 @@ func (in *CustomResourceValidation) DeepCopyInto(out *CustomResourceValidation) if *in == nil { *out = nil } else { - *out = (*in).DeepCopy() + *out = new(JSONSchemaProps) + (*in).DeepCopyInto(*out) } } return @@ -323,50 +237,6 @@ func (in *JSON) DeepCopy() *JSON { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in JSONSchemaDefinitions) DeepCopyInto(out *JSONSchemaDefinitions) { - { - in := &in - *out = make(JSONSchemaDefinitions, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - return - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONSchemaDefinitions. -func (in JSONSchemaDefinitions) DeepCopy() JSONSchemaDefinitions { - if in == nil { - return nil - } - out := new(JSONSchemaDefinitions) - in.DeepCopyInto(out) - return *out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in JSONSchemaDependencies) DeepCopyInto(out *JSONSchemaDependencies) { - { - in := &in - *out = make(JSONSchemaDependencies, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - return - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONSchemaDependencies. -func (in JSONSchemaDependencies) DeepCopy() JSONSchemaDependencies { - if in == nil { - return nil - } - out := new(JSONSchemaDependencies) - in.DeepCopyInto(out) - return *out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *JSONSchemaProps) DeepCopyInto(out *JSONSchemaProps) { clone := in.DeepCopy() @@ -382,7 +252,8 @@ func (in *JSONSchemaPropsOrArray) DeepCopyInto(out *JSONSchemaPropsOrArray) { if *in == nil { *out = nil } else { - *out = (*in).DeepCopy() + *out = new(JSONSchemaProps) + (*in).DeepCopyInto(*out) } } if in.JSONSchemas != nil { @@ -413,7 +284,8 @@ func (in *JSONSchemaPropsOrBool) DeepCopyInto(out *JSONSchemaPropsOrBool) { if *in == nil { *out = nil } else { - *out = (*in).DeepCopy() + *out = new(JSONSchemaProps) + (*in).DeepCopyInto(*out) } } return @@ -437,7 +309,8 @@ func (in *JSONSchemaPropsOrStringArray) DeepCopyInto(out *JSONSchemaPropsOrStrin if *in == nil { *out = nil } else { - *out = (*in).DeepCopy() + *out = new(JSONSchemaProps) + (*in).DeepCopyInto(*out) } } if in.Property != nil { diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.defaults.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.defaults.go index 546f33eda..55798082e 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.defaults.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1/zz_generated.defaults.go @@ -1,7 +1,7 @@ // +build !ignore_autogenerated /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by defaulter-gen. DO NOT EDIT. +// This file was autogenerated by defaulter-gen. Do not edit it manually! package v1beta1 diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/BUILD b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/BUILD index b641b6093..25b1bbd59 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/BUILD +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/BUILD @@ -11,8 +11,8 @@ go_library( srcs = ["validation.go"], importpath = "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation", deps = [ + "//vendor/github.com/go-openapi/spec:go_default_library", "//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library", - "//vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/validation:go_default_library", "//vendor/k8s.io/apiextensions-apiserver/pkg/features:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/validation:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library", @@ -24,7 +24,8 @@ go_library( go_test( name = "go_default_test", srcs = ["validation_test.go"], - embed = [":go_default_library"], + importpath = "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation", + library = ":go_default_library", deps = [ "//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go index 713fcfa90..f064b9933 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go @@ -18,16 +18,16 @@ package validation import ( "fmt" - "reflect" "strings" + "github.com/go-openapi/spec" + genericvalidation "k8s.io/apimachinery/pkg/api/validation" validationutil "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation/field" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" - apiservervalidation "k8s.io/apiextensions-apiserver/pkg/apiserver/validation" apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features" ) @@ -108,13 +108,7 @@ func ValidateCustomResourceDefinitionSpec(spec *apiextensions.CustomResourceDefi if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceValidation) { allErrs = append(allErrs, ValidateCustomResourceDefinitionValidation(spec.Validation, fldPath.Child("validation"))...) } else if spec.Validation != nil { - allErrs = append(allErrs, field.Forbidden(fldPath.Child("validation"), "disabled by feature-gate CustomResourceValidation")) - } - - if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) { - allErrs = append(allErrs, ValidateCustomResourceDefinitionSubresources(spec.Subresources, fldPath.Child("subresources"))...) - } else if spec.Subresources != nil { - allErrs = append(allErrs, field.Forbidden(fldPath.Child("subresources"), "disabled by feature-gate CustomResourceSubresources")) + allErrs = append(allErrs, field.Forbidden(fldPath.Child("validation"), "disabled by feature-gate")) } return allErrs @@ -165,6 +159,7 @@ func ValidateCustomResourceDefinitionNames(names *apiextensions.CustomResourceDe if errs := validationutil.IsDNS1035Label(shortName); len(errs) > 0 { allErrs = append(allErrs, field.Invalid(fldPath.Child("shortNames").Index(i), shortName, strings.Join(errs, ","))) } + } // kind and listKind may not be the same or parsing become ambiguous @@ -172,16 +167,10 @@ func ValidateCustomResourceDefinitionNames(names *apiextensions.CustomResourceDe allErrs = append(allErrs, field.Invalid(fldPath.Child("listKind"), names.ListKind, "kind and listKind may not be the same")) } - for i, category := range names.Categories { - if errs := validationutil.IsDNS1035Label(category); len(errs) > 0 { - allErrs = append(allErrs, field.Invalid(fldPath.Child("categories").Index(i), category, strings.Join(errs, ","))) - } - } - return allErrs } -// specStandardValidator applies validations for different OpenAPI specification versions. +// specStandardValidator applies validations for different OpenAPI specfication versions. type specStandardValidator interface { validate(spec *apiextensions.JSONSchemaProps, fldPath *field.Path) field.ErrorList } @@ -194,35 +183,11 @@ func ValidateCustomResourceDefinitionValidation(customResourceValidation *apiext return allErrs } - if schema := customResourceValidation.OpenAPIV3Schema; schema != nil { - // if subresources are enabled, only properties is allowed inside the root schema - if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) { - v := reflect.ValueOf(schema).Elem() - fieldsPresent := 0 - - for i := 0; i < v.NumField(); i++ { - field := v.Field(i).Interface() - if !reflect.DeepEqual(field, reflect.Zero(reflect.TypeOf(field)).Interface()) { - fieldsPresent++ - } - } - - if fieldsPresent > 1 || (fieldsPresent == 1 && v.FieldByName("Properties").IsNil()) { - allErrs = append(allErrs, field.Invalid(fldPath.Child("openAPIV3Schema"), *schema, fmt.Sprintf("if subresources for custom resources are enabled, only properties can be used at the root of the schema"))) - return allErrs - } - } - + if customResourceValidation.OpenAPIV3Schema != nil { openAPIV3Schema := &specStandardValidatorV3{} - allErrs = append(allErrs, ValidateCustomResourceDefinitionOpenAPISchema(schema, fldPath.Child("openAPIV3Schema"), openAPIV3Schema)...) + allErrs = append(allErrs, ValidateCustomResourceDefinitionOpenAPISchema(customResourceValidation.OpenAPIV3Schema, fldPath.Child("openAPIV3Schema"), openAPIV3Schema)...) } - // if validation passed otherwise, make sure we can actually construct a schema validator from this custom resource validation. - if len(allErrs) == 0 { - if _, _, err := apiservervalidation.NewSchemaValidator(customResourceValidation); err != nil { - allErrs = append(allErrs, field.Invalid(fldPath, "", fmt.Sprintf("error building validator: %v", err))) - } - } return allErrs } @@ -248,6 +213,17 @@ func ValidateCustomResourceDefinitionOpenAPISchema(schema *apiextensions.JSONSch allErrs = append(allErrs, ValidateCustomResourceDefinitionOpenAPISchema(schema.AdditionalProperties.Schema, fldPath.Child("additionalProperties"), ssv)...) } + if schema.Ref != nil { + openapiRef, err := spec.NewRef(*schema.Ref) + if err != nil { + allErrs = append(allErrs, field.Invalid(fldPath.Child("ref"), *schema.Ref, err.Error())) + } + + if !openapiRef.IsValidURI() { + allErrs = append(allErrs, field.Invalid(fldPath.Child("ref"), *schema.Ref, "ref does not point to a valid URI")) + } + } + if schema.AdditionalItems != nil { allErrs = append(allErrs, ValidateCustomResourceDefinitionOpenAPISchema(schema.AdditionalItems.Schema, fldPath.Child("additionalItems"), ssv)...) } @@ -342,10 +318,6 @@ func (v *specStandardValidatorV3) validate(schema *apiextensions.JSONSchemaProps allErrs = append(allErrs, field.Forbidden(fldPath.Child("dependencies"), "dependencies is not supported")) } - if schema.Ref != nil { - allErrs = append(allErrs, field.Forbidden(fldPath.Child("$ref"), "$ref is not supported")) - } - if schema.Type == "null" { allErrs = append(allErrs, field.Forbidden(fldPath.Child("type"), "type cannot be set to null")) } @@ -356,64 +328,3 @@ func (v *specStandardValidatorV3) validate(schema *apiextensions.JSONSchemaProps return allErrs } - -// ValidateCustomResourceDefinitionSubresources statically validates -func ValidateCustomResourceDefinitionSubresources(subresources *apiextensions.CustomResourceSubresources, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - - if subresources == nil { - return allErrs - } - - if subresources.Scale != nil { - if len(subresources.Scale.SpecReplicasPath) == 0 { - allErrs = append(allErrs, field.Required(fldPath.Child("scale.specReplicasPath"), "")) - } else { - // should be constrained json path under .spec - if errs := validateSimpleJSONPath(subresources.Scale.SpecReplicasPath, fldPath.Child("scale.specReplicasPath")); len(errs) > 0 { - allErrs = append(allErrs, errs...) - } else if !strings.HasPrefix(subresources.Scale.SpecReplicasPath, ".spec.") { - allErrs = append(allErrs, field.Invalid(fldPath.Child("scale.specReplicasPath"), subresources.Scale.SpecReplicasPath, "should be a json path under .spec")) - } - } - - if len(subresources.Scale.StatusReplicasPath) == 0 { - allErrs = append(allErrs, field.Required(fldPath.Child("scale.statusReplicasPath"), "")) - } else { - // should be constrained json path under .status - if errs := validateSimpleJSONPath(subresources.Scale.StatusReplicasPath, fldPath.Child("scale.statusReplicasPath")); len(errs) > 0 { - allErrs = append(allErrs, errs...) - } else if !strings.HasPrefix(subresources.Scale.StatusReplicasPath, ".status.") { - allErrs = append(allErrs, field.Invalid(fldPath.Child("scale.statusReplicasPath"), subresources.Scale.StatusReplicasPath, "should be a json path under .status")) - } - } - - // if labelSelectorPath is present, it should be a constrained json path under .status - if subresources.Scale.LabelSelectorPath != nil && len(*subresources.Scale.LabelSelectorPath) > 0 { - if errs := validateSimpleJSONPath(*subresources.Scale.LabelSelectorPath, fldPath.Child("scale.labelSelectorPath")); len(errs) > 0 { - allErrs = append(allErrs, errs...) - } else if !strings.HasPrefix(*subresources.Scale.LabelSelectorPath, ".status.") { - allErrs = append(allErrs, field.Invalid(fldPath.Child("scale.labelSelectorPath"), subresources.Scale.LabelSelectorPath, "should be a json path under .status")) - } - } - } - - return allErrs -} - -func validateSimpleJSONPath(s string, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - - switch { - case len(s) == 0: - allErrs = append(allErrs, field.Invalid(fldPath, s, "must not be empty")) - case s[0] != '.': - allErrs = append(allErrs, field.Invalid(fldPath, s, "must be a simple json path starting with .")) - case s != ".": - if cs := strings.Split(s[1:], "."); len(cs) < 1 { - allErrs = append(allErrs, field.Invalid(fldPath, s, "must be a json path in the dot notation")) - } - } - - return allErrs -} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/zz_generated.deepcopy.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/zz_generated.deepcopy.go index ea3af6976..f7d57c22e 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/zz_generated.deepcopy.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ // +build !ignore_autogenerated /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by deepcopy-gen. DO NOT EDIT. +// This file was autogenerated by deepcopy-gen. Do not edit it manually! package apiextensions @@ -48,8 +48,9 @@ func (in *CustomResourceDefinition) DeepCopy() *CustomResourceDefinition { func (in *CustomResourceDefinition) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c + } else { + return nil } - return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -98,8 +99,9 @@ func (in *CustomResourceDefinitionList) DeepCopy() *CustomResourceDefinitionList func (in *CustomResourceDefinitionList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c + } else { + return nil } - return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -110,11 +112,6 @@ func (in *CustomResourceDefinitionNames) DeepCopyInto(out *CustomResourceDefinit *out = make([]string, len(*in)) copy(*out, *in) } - if in.Categories != nil { - in, out := &in.Categories, &out.Categories - *out = make([]string, len(*in)) - copy(*out, *in) - } return } @@ -141,15 +138,6 @@ func (in *CustomResourceDefinitionSpec) DeepCopyInto(out *CustomResourceDefiniti (*in).DeepCopyInto(*out) } } - if in.Subresources != nil { - in, out := &in.Subresources, &out.Subresources - if *in == nil { - *out = nil - } else { - *out = new(CustomResourceSubresources) - (*in).DeepCopyInto(*out) - } - } return } @@ -187,81 +175,6 @@ func (in *CustomResourceDefinitionStatus) DeepCopy() *CustomResourceDefinitionSt return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CustomResourceSubresourceScale) DeepCopyInto(out *CustomResourceSubresourceScale) { - *out = *in - if in.LabelSelectorPath != nil { - in, out := &in.LabelSelectorPath, &out.LabelSelectorPath - if *in == nil { - *out = nil - } else { - *out = new(string) - **out = **in - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceSubresourceScale. -func (in *CustomResourceSubresourceScale) DeepCopy() *CustomResourceSubresourceScale { - if in == nil { - return nil - } - out := new(CustomResourceSubresourceScale) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CustomResourceSubresourceStatus) DeepCopyInto(out *CustomResourceSubresourceStatus) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceSubresourceStatus. -func (in *CustomResourceSubresourceStatus) DeepCopy() *CustomResourceSubresourceStatus { - if in == nil { - return nil - } - out := new(CustomResourceSubresourceStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CustomResourceSubresources) DeepCopyInto(out *CustomResourceSubresources) { - *out = *in - if in.Status != nil { - in, out := &in.Status, &out.Status - if *in == nil { - *out = nil - } else { - *out = new(CustomResourceSubresourceStatus) - **out = **in - } - } - if in.Scale != nil { - in, out := &in.Scale, &out.Scale - if *in == nil { - *out = nil - } else { - *out = new(CustomResourceSubresourceScale) - (*in).DeepCopyInto(*out) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomResourceSubresources. -func (in *CustomResourceSubresources) DeepCopy() *CustomResourceSubresources { - if in == nil { - return nil - } - out := new(CustomResourceSubresources) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CustomResourceValidation) DeepCopyInto(out *CustomResourceValidation) { *out = *in @@ -270,7 +183,8 @@ func (in *CustomResourceValidation) DeepCopyInto(out *CustomResourceValidation) if *in == nil { *out = nil } else { - *out = (*in).DeepCopy() + *out = new(JSONSchemaProps) + (*in).DeepCopyInto(*out) } } return @@ -302,50 +216,6 @@ func (in *ExternalDocumentation) DeepCopy() *ExternalDocumentation { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in JSONSchemaDefinitions) DeepCopyInto(out *JSONSchemaDefinitions) { - { - in := &in - *out = make(JSONSchemaDefinitions, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - return - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONSchemaDefinitions. -func (in JSONSchemaDefinitions) DeepCopy() JSONSchemaDefinitions { - if in == nil { - return nil - } - out := new(JSONSchemaDefinitions) - in.DeepCopyInto(out) - return *out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in JSONSchemaDependencies) DeepCopyInto(out *JSONSchemaDependencies) { - { - in := &in - *out = make(JSONSchemaDependencies, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - return - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JSONSchemaDependencies. -func (in JSONSchemaDependencies) DeepCopy() JSONSchemaDependencies { - if in == nil { - return nil - } - out := new(JSONSchemaDependencies) - in.DeepCopyInto(out) - return *out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *JSONSchemaProps) DeepCopyInto(out *JSONSchemaProps) { clone := in.DeepCopy() @@ -361,7 +231,8 @@ func (in *JSONSchemaPropsOrArray) DeepCopyInto(out *JSONSchemaPropsOrArray) { if *in == nil { *out = nil } else { - *out = (*in).DeepCopy() + *out = new(JSONSchemaProps) + (*in).DeepCopyInto(*out) } } if in.JSONSchemas != nil { @@ -392,7 +263,8 @@ func (in *JSONSchemaPropsOrBool) DeepCopyInto(out *JSONSchemaPropsOrBool) { if *in == nil { *out = nil } else { - *out = (*in).DeepCopy() + *out = new(JSONSchemaProps) + (*in).DeepCopyInto(*out) } } return @@ -416,7 +288,8 @@ func (in *JSONSchemaPropsOrStringArray) DeepCopyInto(out *JSONSchemaPropsOrStrin if *in == nil { *out = nil } else { - *out = (*in).DeepCopy() + *out = new(JSONSchemaProps) + (*in).DeepCopyInto(*out) } } if in.Property != nil { diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/BUILD b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/BUILD index 09d21156d..7b5d2d283 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/BUILD +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/BUILD @@ -20,7 +20,6 @@ go_library( "//vendor/github.com/go-openapi/strfmt:go_default_library", "//vendor/github.com/go-openapi/validate:go_default_library", "//vendor/github.com/golang/glog:go_default_library", - "//vendor/k8s.io/api/autoscaling/v1:go_default_library", "//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library", "//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install:go_default_library", "//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library", @@ -33,9 +32,7 @@ go_library( "//vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion:go_default_library", "//vendor/k8s.io/apiextensions-apiserver/pkg/controller/finalizer:go_default_library", "//vendor/k8s.io/apiextensions-apiserver/pkg/controller/status:go_default_library", - "//vendor/k8s.io/apiextensions-apiserver/pkg/features:go_default_library", "//vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource:go_default_library", - "//vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor:go_default_library", "//vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", @@ -57,19 +54,13 @@ go_library( "//vendor/k8s.io/apiserver/pkg/admission:go_default_library", "//vendor/k8s.io/apiserver/pkg/endpoints/discovery:go_default_library", "//vendor/k8s.io/apiserver/pkg/endpoints/handlers:go_default_library", - "//vendor/k8s.io/apiserver/pkg/endpoints/handlers/responsewriters:go_default_library", - "//vendor/k8s.io/apiserver/pkg/endpoints/metrics:go_default_library", "//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library", "//vendor/k8s.io/apiserver/pkg/registry/generic:go_default_library", "//vendor/k8s.io/apiserver/pkg/registry/generic/registry:go_default_library", "//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library", "//vendor/k8s.io/apiserver/pkg/server:go_default_library", - "//vendor/k8s.io/apiserver/pkg/server/storage:go_default_library", "//vendor/k8s.io/apiserver/pkg/storage/storagebackend:go_default_library", - "//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library", "//vendor/k8s.io/client-go/discovery:go_default_library", - "//vendor/k8s.io/client-go/scale:go_default_library", - "//vendor/k8s.io/client-go/scale/scheme/autoscalingv1:go_default_library", "//vendor/k8s.io/client-go/tools/cache:go_default_library", "//vendor/k8s.io/client-go/util/workqueue:go_default_library", ], @@ -94,6 +85,7 @@ filegroup( go_test( name = "go_default_test", srcs = ["customresource_handler_test.go"], - embed = [":go_default_library"], + importpath = "k8s.io/apiextensions-apiserver/pkg/apiserver", + library = ":go_default_library", deps = ["//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library"], ) diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/apiserver.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/apiserver.go index 1415ff8d9..de90cef90 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/apiserver.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/apiserver.go @@ -35,7 +35,6 @@ import ( genericregistry "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" genericapiserver "k8s.io/apiserver/pkg/server" - serverstorage "k8s.io/apiserver/pkg/server/storage" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install" @@ -54,7 +53,7 @@ import ( var ( groupFactoryRegistry = make(announced.APIGroupFactoryRegistry) - Registry = registered.NewOrDie("") + registry = registered.NewOrDie("") Scheme = runtime.NewScheme() Codecs = serializer.NewCodecFactory(Scheme) @@ -71,7 +70,7 @@ var ( ) func init() { - install.Install(groupFactoryRegistry, Registry, Scheme) + install.Install(groupFactoryRegistry, registry, Scheme) // we need to add the options to empty v1 metav1.AddToGroupVersion(Scheme, schema.GroupVersion{Group: "", Version: "v1"}) @@ -132,18 +131,13 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget) GenericAPIServer: genericServer, } - apiResourceConfig := c.GenericConfig.MergedResourceConfig - apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apiextensions.GroupName, Registry, Scheme, metav1.ParameterCodec, Codecs) - if apiResourceConfig.VersionEnabled(v1beta1.SchemeGroupVersion) { - apiGroupInfo.GroupMeta.GroupVersion = v1beta1.SchemeGroupVersion - storage := map[string]rest.Storage{} - // customresourcedefinitions - customResourceDefintionStorage := customresourcedefinition.NewREST(Scheme, c.GenericConfig.RESTOptionsGetter) - storage["customresourcedefinitions"] = customResourceDefintionStorage - storage["customresourcedefinitions/status"] = customresourcedefinition.NewStatusREST(Scheme, customResourceDefintionStorage) - - apiGroupInfo.VersionedResourcesStorageMap["v1beta1"] = storage - } + apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apiextensions.GroupName, registry, Scheme, metav1.ParameterCodec, Codecs) + apiGroupInfo.GroupMeta.GroupVersion = v1beta1.SchemeGroupVersion + customResourceDefintionStorage := customresourcedefinition.NewREST(Scheme, c.GenericConfig.RESTOptionsGetter) + v1beta1storage := map[string]rest.Storage{} + v1beta1storage["customresourcedefinitions"] = customResourceDefintionStorage + v1beta1storage["customresourcedefinitions/status"] = customresourcedefinition.NewStatusREST(Scheme, customResourceDefintionStorage) + apiGroupInfo.VersionedResourcesStorageMap["v1beta1"] = v1beta1storage if err := s.GenericAPIServer.InstallAPIGroup(&apiGroupInfo); err != nil { return nil, err @@ -183,6 +177,7 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget) versionDiscoveryHandler, groupDiscoveryHandler, s.GenericAPIServer.RequestContextMapper(), + s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions().Lister(), s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions(), delegateHandler, c.ExtraConfig.CRDRESTOptionsGetter, @@ -217,13 +212,3 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget) return s, nil } - -func DefaultAPIResourceConfigSource() *serverstorage.ResourceConfig { - ret := serverstorage.NewResourceConfig() - // NOTE: GroupVersions listed here will be enabled by default. Don't put alpha versions in the list. - ret.EnableVersions( - v1beta1.SchemeGroupVersion, - ) - - return ret -} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_discovery_controller.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_discovery_controller.go index b180e105b..85a2a27d0 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_discovery_controller.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_discovery_controller.go @@ -22,7 +22,6 @@ import ( "github.com/golang/glog" - autoscaling "k8s.io/api/autoscaling/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime/schema" @@ -117,28 +116,7 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error { Kind: crd.Status.AcceptedNames.Kind, Verbs: verbs, ShortNames: crd.Status.AcceptedNames.ShortNames, - Categories: crd.Status.AcceptedNames.Categories, }) - - if crd.Spec.Subresources != nil && crd.Spec.Subresources.Status != nil { - apiResourcesForDiscovery = append(apiResourcesForDiscovery, metav1.APIResource{ - Name: crd.Status.AcceptedNames.Plural + "/status", - Namespaced: crd.Spec.Scope == apiextensions.NamespaceScoped, - Kind: crd.Status.AcceptedNames.Kind, - Verbs: metav1.Verbs([]string{"get", "patch", "update"}), - }) - } - - if crd.Spec.Subresources != nil && crd.Spec.Subresources.Scale != nil { - apiResourcesForDiscovery = append(apiResourcesForDiscovery, metav1.APIResource{ - Group: autoscaling.GroupName, - Version: "v1", - Kind: "Scale", - Name: crd.Status.AcceptedNames.Plural + "/scale", - Namespaced: crd.Spec.Scope == apiextensions.NamespaceScoped, - Verbs: metav1.Verbs([]string{"get", "patch", "update"}), - }) - } } if !foundGroup { diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go index e427f4c11..773a06577 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go @@ -18,14 +18,14 @@ package apiserver import ( "fmt" + "io" "net/http" "path" - "strings" "sync" "sync/atomic" "time" - "github.com/go-openapi/spec" + openapispec "github.com/go-openapi/spec" "github.com/go-openapi/strfmt" "github.com/go-openapi/validate" "github.com/golang/glog" @@ -38,33 +38,25 @@ import ( "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/runtime/serializer/json" "k8s.io/apimachinery/pkg/runtime/serializer/versioning" "k8s.io/apimachinery/pkg/types" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/endpoints/handlers" - "k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" - "k8s.io/apiserver/pkg/endpoints/metrics" apirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/registry/generic" genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" "k8s.io/apiserver/pkg/storage/storagebackend" - utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/discovery" - "k8s.io/client-go/scale" - "k8s.io/client-go/scale/scheme/autoscalingv1" - "k8s.io/client-go/tools/cache" + cache "k8s.io/client-go/tools/cache" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" apiservervalidation "k8s.io/apiextensions-apiserver/pkg/apiserver/validation" informers "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion" listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion" "k8s.io/apiextensions-apiserver/pkg/controller/finalizer" - apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features" "k8s.io/apiextensions-apiserver/pkg/registry/customresource" - "k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor" ) // crdHandler serves the `/apis` endpoint. @@ -75,9 +67,6 @@ type crdHandler struct { customStorageLock sync.Mutex // customStorage contains a crdStorageMap - // atomic.Value has a very good read performance compared to sync.RWMutex - // see https://gist.github.com/dim/152e6bf80e1384ea72e17ac717a5000a - // which is suited for most read and rarely write cases customStorage atomic.Value requestContextMapper apirequest.RequestContextMapper @@ -96,11 +85,8 @@ type crdInfo struct { spec *apiextensions.CustomResourceDefinitionSpec acceptedNames *apiextensions.CustomResourceDefinitionNames - storage customresource.CustomResourceStorage - - requestScope handlers.RequestScope - scaleRequestScope handlers.RequestScope - statusRequestScope handlers.RequestScope + storage *customresource.REST + requestScope handlers.RequestScope } // crdStorageMap goes from customresourcedefinition to its storage @@ -110,6 +96,7 @@ func NewCustomResourceDefinitionHandler( versionDiscoveryHandler *versionDiscoveryHandler, groupDiscoveryHandler *groupDiscoveryHandler, requestContextMapper apirequest.RequestContextMapper, + crdLister listers.CustomResourceDefinitionLister, crdInformer informers.CustomResourceDefinitionInformer, delegate http.Handler, restOptionsGetter generic.RESTOptionsGetter, @@ -119,7 +106,7 @@ func NewCustomResourceDefinitionHandler( groupDiscoveryHandler: groupDiscoveryHandler, customStorage: atomic.Value{}, requestContextMapper: requestContextMapper, - crdLister: crdInformer.Lister(), + crdLister: crdLister, delegate: delegate, restOptionsGetter: restOptionsGetter, admission: admission, @@ -133,20 +120,19 @@ func NewCustomResourceDefinitionHandler( }) ret.customStorage.Store(crdStorageMap{}) - return ret } func (r *crdHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { ctx, ok := r.requestContextMapper.Get(req) if !ok { - responsewriters.InternalError(w, req, fmt.Errorf("no context found for request")) - return + // programmer error + panic("missing context") } requestInfo, ok := apirequest.RequestInfoFrom(ctx) if !ok { - responsewriters.InternalError(w, req, fmt.Errorf("no RequestInfo found in the context")) - return + // programmer error + panic("missing requestInfo") } if !requestInfo.IsResourceRequest { pathParts := splitPath(requestInfo.Path) @@ -182,162 +168,93 @@ func (r *crdHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { } if !apiextensions.IsCRDConditionTrue(crd, apiextensions.Established) { r.delegate.ServeHTTP(w, req) + } + if len(requestInfo.Subresource) > 0 { + http.NotFound(w, req) return } terminating := apiextensions.IsCRDConditionTrue(crd, apiextensions.Terminating) - crdInfo, err := r.getOrCreateServingInfoFor(crd) + crdInfo, err := r.getServingInfoFor(crd) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } - verb := strings.ToUpper(requestInfo.Verb) - resource := requestInfo.Resource - subresource := requestInfo.Subresource - scope := metrics.CleanScope(requestInfo) - supportedTypes := []string{ - string(types.JSONPatchType), - string(types.MergePatchType), - } - - var handler http.HandlerFunc - switch { - case subresource == "status" && crd.Spec.Subresources != nil && crd.Spec.Subresources.Status != nil: - handler = r.serveStatus(w, req, requestInfo, crdInfo, terminating, supportedTypes) - case subresource == "scale" && crd.Spec.Subresources != nil && crd.Spec.Subresources.Scale != nil: - handler = r.serveScale(w, req, requestInfo, crdInfo, terminating, supportedTypes) - case len(subresource) == 0: - handler = r.serveResource(w, req, requestInfo, crdInfo, terminating, supportedTypes) - default: - http.Error(w, "the server could not find the requested resource", http.StatusNotFound) - } - - if handler != nil { - handler = metrics.InstrumentHandlerFunc(verb, resource, subresource, scope, handler) - handler(w, req) - return - } -} - -func (r *crdHandler) serveResource(w http.ResponseWriter, req *http.Request, requestInfo *apirequest.RequestInfo, crdInfo *crdInfo, terminating bool, supportedTypes []string) http.HandlerFunc { + storage := crdInfo.storage requestScope := crdInfo.requestScope - storage := crdInfo.storage.CustomResource minRequestTimeout := 1 * time.Minute switch requestInfo.Verb { case "get": - return handlers.GetResource(storage, storage, requestScope) + handler := handlers.GetResource(storage, storage, requestScope) + handler(w, req) + return case "list": forceWatch := false - return handlers.ListResource(storage, storage, requestScope, forceWatch, minRequestTimeout) + handler := handlers.ListResource(storage, storage, requestScope, forceWatch, minRequestTimeout) + handler(w, req) + return case "watch": forceWatch := true - return handlers.ListResource(storage, storage, requestScope, forceWatch, minRequestTimeout) + handler := handlers.ListResource(storage, storage, requestScope, forceWatch, minRequestTimeout) + handler(w, req) + return case "create": if terminating { http.Error(w, fmt.Sprintf("%v not allowed while CustomResourceDefinition is terminating", requestInfo.Verb), http.StatusMethodNotAllowed) - return nil + return } - return handlers.CreateResource(storage, requestScope, discovery.NewUnstructuredObjectTyper(nil), r.admission) + handler := handlers.CreateResource(storage, requestScope, discovery.NewUnstructuredObjectTyper(nil), r.admission) + handler(w, req) + return case "update": - return handlers.UpdateResource(storage, requestScope, discovery.NewUnstructuredObjectTyper(nil), r.admission) + if terminating { + http.Error(w, fmt.Sprintf("%v not allowed while CustomResourceDefinition is terminating", requestInfo.Verb), http.StatusMethodNotAllowed) + return + } + handler := handlers.UpdateResource(storage, requestScope, discovery.NewUnstructuredObjectTyper(nil), r.admission) + handler(w, req) + return case "patch": - return handlers.PatchResource(storage, requestScope, r.admission, unstructured.UnstructuredObjectConverter{}, supportedTypes) + if terminating { + http.Error(w, fmt.Sprintf("%v not allowed while CustomResourceDefinition is terminating", requestInfo.Verb), http.StatusMethodNotAllowed) + return + } + handler := handlers.PatchResource(storage, requestScope, r.admission, unstructured.UnstructuredObjectConverter{}) + handler(w, req) + return case "delete": allowsOptions := true - return handlers.DeleteResource(storage, allowsOptions, requestScope, r.admission) + handler := handlers.DeleteResource(storage, allowsOptions, requestScope, r.admission) + handler(w, req) + return case "deletecollection": checkBody := true - return handlers.DeleteCollection(storage, checkBody, requestScope, r.admission) + handler := handlers.DeleteCollection(storage, checkBody, requestScope, r.admission) + handler(w, req) + return + default: http.Error(w, fmt.Sprintf("unhandled verb %q", requestInfo.Verb), http.StatusMethodNotAllowed) - return nil - } -} - -func (r *crdHandler) serveStatus(w http.ResponseWriter, req *http.Request, requestInfo *apirequest.RequestInfo, crdInfo *crdInfo, terminating bool, supportedTypes []string) http.HandlerFunc { - requestScope := crdInfo.statusRequestScope - storage := crdInfo.storage.Status - - switch requestInfo.Verb { - case "get": - return handlers.GetResource(storage, nil, requestScope) - case "update": - return handlers.UpdateResource(storage, requestScope, discovery.NewUnstructuredObjectTyper(nil), r.admission) - case "patch": - return handlers.PatchResource(storage, requestScope, r.admission, unstructured.UnstructuredObjectConverter{}, supportedTypes) - default: - http.Error(w, fmt.Sprintf("unhandled verb %q", requestInfo.Verb), http.StatusMethodNotAllowed) - return nil - } -} - -func (r *crdHandler) serveScale(w http.ResponseWriter, req *http.Request, requestInfo *apirequest.RequestInfo, crdInfo *crdInfo, terminating bool, supportedTypes []string) http.HandlerFunc { - requestScope := crdInfo.scaleRequestScope - storage := crdInfo.storage.Scale - - switch requestInfo.Verb { - case "get": - return handlers.GetResource(storage, nil, requestScope) - case "update": - return handlers.UpdateResource(storage, requestScope, discovery.NewUnstructuredObjectTyper(nil), r.admission) - case "patch": - return handlers.PatchResource(storage, requestScope, r.admission, unstructured.UnstructuredObjectConverter{}, supportedTypes) - default: - http.Error(w, fmt.Sprintf("unhandled verb %q", requestInfo.Verb), http.StatusMethodNotAllowed) - return nil - } -} - -func (r *crdHandler) updateCustomResourceDefinition(oldObj, newObj interface{}) { - oldCRD := oldObj.(*apiextensions.CustomResourceDefinition) - newCRD := newObj.(*apiextensions.CustomResourceDefinition) - - r.customStorageLock.Lock() - defer r.customStorageLock.Unlock() - - storageMap := r.customStorage.Load().(crdStorageMap) - oldInfo, found := storageMap[newCRD.UID] - if !found { return } - if apiequality.Semantic.DeepEqual(&newCRD.Spec, oldInfo.spec) && apiequality.Semantic.DeepEqual(&newCRD.Status.AcceptedNames, oldInfo.acceptedNames) { - glog.V(6).Infof("Ignoring customresourcedefinition %s update because neither spec, nor accepted names changed", oldCRD.Name) - return - } - - glog.V(4).Infof("Updating customresourcedefinition %s", oldCRD.Name) - - // Copy because we cannot write to storageMap without a race - // as it is used without locking elsewhere. - storageMap2 := storageMap.clone() - if oldInfo, ok := storageMap2[types.UID(oldCRD.UID)]; ok { - // destroy only the main storage. Those for the subresources share cacher and etcd clients. - oldInfo.storage.CustomResource.DestroyFunc() - delete(storageMap2, types.UID(oldCRD.UID)) - } - - r.customStorage.Store(storageMap2) } // removeDeadStorage removes REST storage that isn't being used func (r *crdHandler) removeDeadStorage() { + // these don't have to be live. A snapshot is fine + // if we wrongly delete, that's ok. The rest storage will be recreated on the next request + // if we wrongly miss one, that's ok. We'll get it next time + storageMap := r.customStorage.Load().(crdStorageMap) allCustomResourceDefinitions, err := r.crdLister.List(labels.Everything()) if err != nil { utilruntime.HandleError(err) return } - r.customStorageLock.Lock() - defer r.customStorageLock.Unlock() - - storageMap := r.customStorage.Load().(crdStorageMap) - // Copy because we cannot write to storageMap without a race - // as it is used without locking elsewhere - storageMap2 := storageMap.clone() - for uid, s := range storageMap2 { + for uid, s := range storageMap { found := false for _, crd := range allCustomResourceDefinitions { if crd.UID == uid { @@ -347,35 +264,39 @@ func (r *crdHandler) removeDeadStorage() { } if !found { glog.V(4).Infof("Removing dead CRD storage for %v", s.requestScope.Resource) - // destroy only the main storage. Those for the subresources share cacher and etcd clients. - s.storage.CustomResource.DestroyFunc() - delete(storageMap2, uid) + s.storage.DestroyFunc() + delete(storageMap, uid) } } - r.customStorage.Store(storageMap2) + + r.customStorageLock.Lock() + defer r.customStorageLock.Unlock() + + r.customStorage.Store(storageMap) } -// GetCustomResourceListerCollectionDeleter returns the ListerCollectionDeleter of -// the given crd. -func (r *crdHandler) GetCustomResourceListerCollectionDeleter(crd *apiextensions.CustomResourceDefinition) (finalizer.ListerCollectionDeleter, error) { - info, err := r.getOrCreateServingInfoFor(crd) +// GetCustomResourceListerCollectionDeleter returns the ListerCollectionDeleter for +// the given uid, or nil if one does not exist. +func (r *crdHandler) GetCustomResourceListerCollectionDeleter(crd *apiextensions.CustomResourceDefinition) finalizer.ListerCollectionDeleter { + info, err := r.getServingInfoFor(crd) if err != nil { - return nil, err + utilruntime.HandleError(err) } - return info.storage.CustomResource, nil + return info.storage } -func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResourceDefinition) (*crdInfo, error) { +func (r *crdHandler) getServingInfoFor(crd *apiextensions.CustomResourceDefinition) (*crdInfo, error) { storageMap := r.customStorage.Load().(crdStorageMap) - if ret, ok := storageMap[crd.UID]; ok { + ret, ok := storageMap[crd.UID] + if ok { return ret, nil } r.customStorageLock.Lock() defer r.customStorageLock.Unlock() - storageMap = r.customStorage.Load().(crdStorageMap) - if ret, ok := storageMap[crd.UID]; ok { + ret, ok = storageMap[crd.UID] + if ok { return ret, nil } @@ -391,46 +312,23 @@ func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResource parameterCodec := runtime.NewParameterCodec(parameterScheme) kind := schema.GroupVersionKind{Group: crd.Spec.Group, Version: crd.Spec.Version, Kind: crd.Status.AcceptedNames.Kind} - typer := UnstructuredObjectTyper{ - Delegate: parameterScheme, - UnstructuredTyper: discovery.NewUnstructuredObjectTyper(nil), + typer := unstructuredObjectTyper{ + delegate: parameterScheme, + unstructuredTyper: discovery.NewUnstructuredObjectTyper(nil), } creator := unstructuredCreator{} - validator, _, err := apiservervalidation.NewSchemaValidator(crd.Spec.Validation) - if err != nil { + // convert CRD schema to openapi schema + openapiSchema := &openapispec.Schema{} + if err := apiservervalidation.ConvertToOpenAPITypes(crd, openapiSchema); err != nil { return nil, err } - - var statusSpec *apiextensions.CustomResourceSubresourceStatus - var statusValidator *validate.SchemaValidator - if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && crd.Spec.Subresources != nil && crd.Spec.Subresources.Status != nil { - statusSpec = crd.Spec.Subresources.Status - - // for the status subresource, validate only against the status schema - if crd.Spec.Validation != nil && crd.Spec.Validation.OpenAPIV3Schema != nil && crd.Spec.Validation.OpenAPIV3Schema.Properties != nil { - if statusSchema, ok := crd.Spec.Validation.OpenAPIV3Schema.Properties["status"]; ok { - openapiSchema := &spec.Schema{} - if err := apiservervalidation.ConvertJSONSchemaProps(&statusSchema, openapiSchema); err != nil { - return nil, err - } - statusValidator = validate.NewSchemaValidator(openapiSchema, nil, "", strfmt.Default) - } - } + if err := openapispec.ExpandSchema(openapiSchema, nil, nil); err != nil { + return nil, err } + validator := validate.NewSchemaValidator(openapiSchema, nil, "", strfmt.Default) - var scaleSpec *apiextensions.CustomResourceSubresourceScale - if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && crd.Spec.Subresources != nil && crd.Spec.Subresources.Scale != nil { - scaleSpec = crd.Spec.Subresources.Scale - } - - // TODO: identify how to pass printer specification from the CRD - table, err := tableconvertor.New(nil) - if err != nil { - glog.V(2).Infof("The CRD for %v has an invalid printer specification, falling back to default printing: %v", kind, err) - } - - customResourceStorage := customresource.NewStorage( + storage := customresource.NewREST( schema.GroupResource{Group: crd.Spec.Group, Resource: crd.Status.AcceptedNames.Plural}, schema.GroupVersionKind{Group: crd.Spec.Group, Version: crd.Spec.Version, Kind: crd.Status.AcceptedNames.ListKind}, customresource.NewStrategy( @@ -438,34 +336,26 @@ func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResource crd.Spec.Scope == apiextensions.NamespaceScoped, kind, validator, - statusValidator, - statusSpec, - scaleSpec, ), r.restOptionsGetter, - crd.Status.AcceptedNames.Categories, - table, ) selfLinkPrefix := "" switch crd.Spec.Scope { case apiextensions.ClusterScoped: - selfLinkPrefix = "/" + path.Join("apis", crd.Spec.Group, crd.Spec.Version) + "/" + crd.Status.AcceptedNames.Plural + "/" + selfLinkPrefix = "/" + path.Join("apis", crd.Spec.Group, crd.Spec.Version) + "/" case apiextensions.NamespaceScoped: selfLinkPrefix = "/" + path.Join("apis", crd.Spec.Group, crd.Spec.Version, "namespaces") + "/" } clusterScoped := crd.Spec.Scope == apiextensions.ClusterScoped - var ctxFn handlers.ContextFunc - ctxFn = func(req *http.Request) apirequest.Context { - ret, _ := r.requestContextMapper.Get(req) - return ret - } - requestScope := handlers.RequestScope{ Namer: handlers.ContextBasedNaming{ - GetContext: ctxFn, + GetContext: func(req *http.Request) apirequest.Context { + ret, _ := r.requestContextMapper.Get(req) + return ret + }, SelfLinker: meta.NewAccessor(), ClusterScoped: clusterScoped, SelfLinkPathPrefix: selfLinkPrefix, @@ -487,54 +377,31 @@ func (r *crdHandler) getOrCreateServingInfoFor(crd *apiextensions.CustomResource Typer: typer, UnsafeConvertor: unstructured.UnstructuredObjectConverter{}, - Resource: schema.GroupVersionResource{Group: crd.Spec.Group, Version: crd.Spec.Version, Resource: crd.Status.AcceptedNames.Plural}, - Kind: kind, + Resource: schema.GroupVersionResource{Group: crd.Spec.Group, Version: crd.Spec.Version, Resource: crd.Status.AcceptedNames.Plural}, + Kind: kind, + Subresource: "", MetaGroupVersion: metav1.SchemeGroupVersion, - - TableConvertor: customResourceStorage.CustomResource, } - ret := &crdInfo{ + ret = &crdInfo{ spec: &crd.Spec, acceptedNames: &crd.Status.AcceptedNames, - storage: customResourceStorage, - requestScope: requestScope, - scaleRequestScope: requestScope, // shallow copy - statusRequestScope: requestScope, // shallow copy + storage: storage, + requestScope: requestScope, } - // override scaleSpec subresource values - scaleConverter := scale.NewScaleConverter() - ret.scaleRequestScope.Subresource = "scale" - ret.scaleRequestScope.Serializer = serializer.NewCodecFactory(scaleConverter.Scheme()) - ret.scaleRequestScope.Kind = autoscalingv1.SchemeGroupVersion.WithKind("Scale") - ret.scaleRequestScope.Namer = handlers.ContextBasedNaming{ - GetContext: ctxFn, - SelfLinker: meta.NewAccessor(), - ClusterScoped: clusterScoped, - SelfLinkPathPrefix: selfLinkPrefix, - SelfLinkPathSuffix: "/scale", - } - - // override status subresource values - ret.statusRequestScope.Subresource = "status" - ret.statusRequestScope.Namer = handlers.ContextBasedNaming{ - GetContext: ctxFn, - SelfLinker: meta.NewAccessor(), - ClusterScoped: clusterScoped, - SelfLinkPathPrefix: selfLinkPrefix, - SelfLinkPathSuffix: "/status", - } + storageMap2 := make(crdStorageMap, len(storageMap)) // Copy because we cannot write to storageMap without a race - // as it is used without locking elsewhere. - storageMap2 := storageMap.clone() + // as it is used without locking elsewhere + for k, v := range storageMap { + storageMap2[k] = v + } storageMap2[crd.UID] = ret r.customStorage.Store(storageMap2) - return ret, nil } @@ -556,6 +423,39 @@ func (c crdObjectConverter) ConvertFieldLabel(version, kind, label, value string } } +func (c *crdHandler) updateCustomResourceDefinition(oldObj, newObj interface{}) { + oldCRD := oldObj.(*apiextensions.CustomResourceDefinition) + newCRD := newObj.(*apiextensions.CustomResourceDefinition) + + c.customStorageLock.Lock() + defer c.customStorageLock.Unlock() + storageMap := c.customStorage.Load().(crdStorageMap) + + oldInfo, found := storageMap[newCRD.UID] + if !found { + return + } + if apiequality.Semantic.DeepEqual(&newCRD.Spec, oldInfo.spec) && apiequality.Semantic.DeepEqual(&newCRD.Status.AcceptedNames, oldInfo.acceptedNames) { + glog.V(6).Infof("Ignoring customresourcedefinition %s update because neither spec, nor accepted names changed", oldCRD.Name) + return + } + + glog.V(4).Infof("Updating customresourcedefinition %s", oldCRD.Name) + storageMap2 := make(crdStorageMap, len(storageMap)) + + // Copy because we cannot write to storageMap without a race + // as it is used without locking elsewhere + for k, v := range storageMap { + if k == oldCRD.UID { + v.storage.DestroyFunc() + continue + } + storageMap2[k] = v + } + + c.customStorage.Store(storageMap2) +} + type unstructuredNegotiatedSerializer struct { typer runtime.ObjectTyper creator runtime.ObjectCreater @@ -574,37 +474,67 @@ func (s unstructuredNegotiatedSerializer) SupportedMediaTypes() []runtime.Serial Framer: json.Framer, }, }, - { - MediaType: "application/yaml", - EncodesAsText: true, - Serializer: json.NewYAMLSerializer(json.DefaultMetaFactory, s.creator, s.typer), - }, } } -func (s unstructuredNegotiatedSerializer) EncoderForVersion(encoder runtime.Encoder, gv runtime.GroupVersioner) runtime.Encoder { - return versioning.NewDefaultingCodecForScheme(Scheme, encoder, nil, gv, nil) +func (s unstructuredNegotiatedSerializer) EncoderForVersion(serializer runtime.Encoder, gv runtime.GroupVersioner) runtime.Encoder { + return versioning.NewDefaultingCodecForScheme(Scheme, crEncoderInstance, nil, gv, nil) } -func (s unstructuredNegotiatedSerializer) DecoderToVersion(decoder runtime.Decoder, gv runtime.GroupVersioner) runtime.Decoder { - return versioning.NewDefaultingCodecForScheme(Scheme, nil, decoder, nil, gv) +func (s unstructuredNegotiatedSerializer) DecoderToVersion(serializer runtime.Decoder, gv runtime.GroupVersioner) runtime.Decoder { + return unstructuredDecoder{delegate: Codecs.DecoderToVersion(serializer, gv)} } -type UnstructuredObjectTyper struct { - Delegate runtime.ObjectTyper - UnstructuredTyper runtime.ObjectTyper +type unstructuredDecoder struct { + delegate runtime.Decoder } -func (t UnstructuredObjectTyper) ObjectKinds(obj runtime.Object) ([]schema.GroupVersionKind, bool, error) { +func (d unstructuredDecoder) Decode(data []byte, defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) { + // Delegate for things other than Unstructured. + if _, ok := into.(runtime.Unstructured); !ok && into != nil { + return d.delegate.Decode(data, defaults, into) + } + return unstructured.UnstructuredJSONScheme.Decode(data, defaults, into) +} + +type unstructuredObjectTyper struct { + delegate runtime.ObjectTyper + unstructuredTyper runtime.ObjectTyper +} + +func (t unstructuredObjectTyper) ObjectKinds(obj runtime.Object) ([]schema.GroupVersionKind, bool, error) { // Delegate for things other than Unstructured. if _, ok := obj.(runtime.Unstructured); !ok { - return t.Delegate.ObjectKinds(obj) + return t.delegate.ObjectKinds(obj) } - return t.UnstructuredTyper.ObjectKinds(obj) + return t.unstructuredTyper.ObjectKinds(obj) } -func (t UnstructuredObjectTyper) Recognizes(gvk schema.GroupVersionKind) bool { - return t.Delegate.Recognizes(gvk) || t.UnstructuredTyper.Recognizes(gvk) +func (t unstructuredObjectTyper) Recognizes(gvk schema.GroupVersionKind) bool { + return t.delegate.Recognizes(gvk) || t.unstructuredTyper.Recognizes(gvk) +} + +var crEncoderInstance = crEncoder{} + +// crEncoder *usually* encodes using the unstructured.UnstructuredJSONScheme, but if the type is Status or WatchEvent +// it will serialize them out using the converting codec. +type crEncoder struct{} + +func (crEncoder) Encode(obj runtime.Object, w io.Writer) error { + switch t := obj.(type) { + case *metav1.Status, *metav1.WatchEvent: + for _, info := range Codecs.SupportedMediaTypes() { + // we are always json + if info.MediaType == "application/json" { + return info.Serializer.Encode(obj, w) + } + } + + return fmt.Errorf("unable to find json serializer for %T", t) + + default: + return unstructured.UnstructuredJSONScheme.Encode(obj, w) + } } type unstructuredCreator struct{} @@ -648,16 +578,3 @@ func (t CRDRESTOptionsGetter) GetRESTOptions(resource schema.GroupResource) (gen } return ret, nil } - -// clone returns a clone of the provided crdStorageMap. -// The clone is a shallow copy of the map. -func (in crdStorageMap) clone() crdStorageMap { - if in == nil { - return nil - } - out := make(crdStorageMap, len(in)) - for key, value := range in { - out[key] = value - } - return out -} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/validation/BUILD b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/validation/BUILD index 3042da88c..a85afaef5 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/validation/BUILD +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/validation/BUILD @@ -12,7 +12,6 @@ go_library( importpath = "k8s.io/apiextensions-apiserver/pkg/apiserver/validation", deps = [ "//vendor/github.com/go-openapi/spec:go_default_library", - "//vendor/github.com/go-openapi/strfmt:go_default_library", "//vendor/github.com/go-openapi/validate:go_default_library", "//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library", ], @@ -34,7 +33,8 @@ filegroup( go_test( name = "go_default_test", srcs = ["validation_test.go"], - embed = [":go_default_library"], + importpath = "k8s.io/apiextensions-apiserver/pkg/apiserver/validation", + library = ":go_default_library", deps = [ "//vendor/github.com/go-openapi/spec:go_default_library", "//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library", diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/validation/validation.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/validation/validation.go index 558ddb1fc..c1cff1417 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/validation/validation.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/validation/validation.go @@ -18,31 +18,14 @@ package validation import ( "github.com/go-openapi/spec" - "github.com/go-openapi/strfmt" "github.com/go-openapi/validate" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" ) -// NewSchemaValidator creates an openapi schema validator for the given CRD validation. -func NewSchemaValidator(customResourceValidation *apiextensions.CustomResourceValidation) (*validate.SchemaValidator, *spec.Schema, error) { - // Convert CRD schema to openapi schema - openapiSchema := &spec.Schema{} - if customResourceValidation != nil { - if err := ConvertJSONSchemaProps(customResourceValidation.OpenAPIV3Schema, openapiSchema); err != nil { - return nil, nil, err - } - } - return validate.NewSchemaValidator(openapiSchema, nil, "", strfmt.Default), openapiSchema, nil -} - // ValidateCustomResource validates the Custom Resource against the schema in the CustomResourceDefinition. // CustomResource is a JSON data structure. func ValidateCustomResource(customResource interface{}, validator *validate.SchemaValidator) error { - if validator == nil { - return nil - } - result := validator.Validate(customResource) if result.AsError() != nil { return result.AsError() @@ -50,8 +33,17 @@ func ValidateCustomResource(customResource interface{}, validator *validate.Sche return nil } -// ConvertJSONSchemaProps converts the schema from apiextensions.JSONSchemaPropos to go-openapi/spec.Schema -func ConvertJSONSchemaProps(in *apiextensions.JSONSchemaProps, out *spec.Schema) error { +// ConvertToOpenAPITypes is used to convert internal types to go-openapi types. +func ConvertToOpenAPITypes(in *apiextensions.CustomResourceDefinition, out *spec.Schema) error { + if in.Spec.Validation != nil { + if err := convertJSONSchemaProps(in.Spec.Validation.OpenAPIV3Schema, out); err != nil { + return err + } + } + return nil +} + +func convertJSONSchemaProps(in *apiextensions.JSONSchemaProps, out *spec.Schema) error { if in == nil { return nil } @@ -104,7 +96,7 @@ func ConvertJSONSchemaProps(in *apiextensions.JSONSchemaProps, out *spec.Schema) if in.Not != nil { in, out := &in.Not, &out.Not *out = new(spec.Schema) - if err := ConvertJSONSchemaProps(*in, *out); err != nil { + if err := convertJSONSchemaProps(*in, *out); err != nil { return err } } @@ -181,7 +173,7 @@ func convertSliceOfJSONSchemaProps(in *[]apiextensions.JSONSchemaProps, out *[]s if in != nil { for _, jsonSchemaProps := range *in { schema := spec.Schema{} - if err := ConvertJSONSchemaProps(&jsonSchemaProps, &schema); err != nil { + if err := convertJSONSchemaProps(&jsonSchemaProps, &schema); err != nil { return err } *out = append(*out, schema) @@ -195,7 +187,7 @@ func convertMapOfJSONSchemaProps(in map[string]apiextensions.JSONSchemaProps) (m if len(in) != 0 { for k, jsonSchemaProps := range in { schema := spec.Schema{} - if err := ConvertJSONSchemaProps(&jsonSchemaProps, &schema); err != nil { + if err := convertJSONSchemaProps(&jsonSchemaProps, &schema); err != nil { return nil, err } out[k] = schema @@ -208,7 +200,7 @@ func convertJSONSchemaPropsOrArray(in *apiextensions.JSONSchemaPropsOrArray, out if in.Schema != nil { in, out := &in.Schema, &out.Schema *out = new(spec.Schema) - if err := ConvertJSONSchemaProps(*in, *out); err != nil { + if err := convertJSONSchemaProps(*in, *out); err != nil { return err } } @@ -216,7 +208,7 @@ func convertJSONSchemaPropsOrArray(in *apiextensions.JSONSchemaPropsOrArray, out in, out := &in.JSONSchemas, &out.Schemas *out = make([]spec.Schema, len(*in)) for i := range *in { - if err := ConvertJSONSchemaProps(&(*in)[i], &(*out)[i]); err != nil { + if err := convertJSONSchemaProps(&(*in)[i], &(*out)[i]); err != nil { return err } } @@ -229,7 +221,7 @@ func convertJSONSchemaPropsorBool(in *apiextensions.JSONSchemaPropsOrBool, out * if in.Schema != nil { in, out := &in.Schema, &out.Schema *out = new(spec.Schema) - if err := ConvertJSONSchemaProps(*in, *out); err != nil { + if err := convertJSONSchemaProps(*in, *out); err != nil { return err } } @@ -241,7 +233,7 @@ func convertJSONSchemaPropsOrStringArray(in *apiextensions.JSONSchemaPropsOrStri if in.Schema != nil { in, out := &in.Schema, &out.Schema *out = new(spec.Schema) - if err := ConvertJSONSchemaProps(*in, *out); err != nil { + if err := convertJSONSchemaProps(*in, *out); err != nil { return err } } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/validation/validation_test.go b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/validation/validation_test.go index 3d9c50c84..a64c48f2d 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/validation/validation_test.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/validation/validation_test.go @@ -58,7 +58,7 @@ func TestRoundTrip(t *testing.T) { // internal -> go-openapi openAPITypes := &spec.Schema{} - if err := ConvertJSONSchemaProps(internal, openAPITypes); err != nil { + if err := convertJSONSchemaProps(internal, openAPITypes); err != nil { t.Fatal(err) } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/clientset.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/clientset.go index 444418888..bae98c78b 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/clientset.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/clientset.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - package clientset import ( diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/doc.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/doc.go index 3421911a7..7f670fed4 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/doc.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - // This package has the automatically generated clientset. package clientset diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake/clientset_generated.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake/clientset_generated.go index 9988cd0b4..473f88f47 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake/clientset_generated.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake/clientset_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - package fake import ( @@ -43,15 +41,7 @@ func NewSimpleClientset(objects ...runtime.Object) *Clientset { fakePtr := testing.Fake{} fakePtr.AddReactor("*", "*", testing.ObjectReaction(o)) - fakePtr.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) { - gvr := action.GetResource() - ns := action.GetNamespace() - watch, err := o.Watch(gvr, ns) - if err != nil { - return false, nil, err - } - return true, watch, nil - }) + fakePtr.AddWatchReactor("*", testing.DefaultWatchReactor(watch.NewFake(), nil)) return &Clientset{fakePtr, &fakediscovery.FakeDiscovery{Fake: &fakePtr}} } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake/doc.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake/doc.go index 0bc260bca..3fd8e1e2c 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake/doc.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - // This package has the automatically generated fake clientset. package fake diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake/register.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake/register.go index 3113c1a6d..857e10e62 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake/register.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake/register.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - package fake import ( @@ -40,7 +38,7 @@ func init() { // // import ( // "k8s.io/client-go/kubernetes" -// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// clientsetscheme "k8s.io/client-go/kuberentes/scheme" // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" // ) // @@ -51,4 +49,5 @@ func init() { // correctly. func AddToScheme(scheme *runtime.Scheme) { apiextensionsv1beta1.AddToScheme(scheme) + } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme/doc.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme/doc.go index 5c5c8debb..3ec2200d0 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme/doc.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - // This package contains the scheme of the automatically generated clientset. package scheme diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme/register.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme/register.go index bc08c37e1..95f4bb41a 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme/register.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme/register.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - package scheme import ( @@ -40,7 +38,7 @@ func init() { // // import ( // "k8s.io/client-go/kubernetes" -// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// clientsetscheme "k8s.io/client-go/kuberentes/scheme" // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" // ) // @@ -51,4 +49,5 @@ func init() { // correctly. func AddToScheme(scheme *runtime.Scheme) { apiextensionsv1beta1.AddToScheme(scheme) + } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/apiextensions_client.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/apiextensions_client.go index 7da7276b7..6a15dadd7 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/apiextensions_client.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/apiextensions_client.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - package v1beta1 import ( diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/customresourcedefinition.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/customresourcedefinition.go index 3a2513caf..73238715b 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/customresourcedefinition.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/customresourcedefinition.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - package v1beta1 import ( diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/doc.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/doc.go index 11ae7049d..1b50aa199 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/doc.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - // This package has the automatically generated typed clients. package v1beta1 diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/fake/doc.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/fake/doc.go index 87a1873ed..c58fac35e 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/fake/doc.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/fake/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - // Package fake has the automatically generated clients. package fake diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/fake/fake_apiextensions_client.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/fake/fake_apiextensions_client.go index 39327a9c3..252845f99 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/fake/fake_apiextensions_client.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/fake/fake_apiextensions_client.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - package fake import ( diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/fake/fake_customresourcedefinition.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/fake/fake_customresourcedefinition.go index 10fd3cc15..7a2edf9ab 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/fake/fake_customresourcedefinition.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/fake/fake_customresourcedefinition.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - package fake import ( diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/generated_expansion.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/generated_expansion.go index 07a7c1dce..2f721078b 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/generated_expansion.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1/generated_expansion.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - package v1beta1 type CustomResourceDefinitionExpansion interface{} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/clientset.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/clientset.go index 9519b78f1..72803e769 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/clientset.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/clientset.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - package internalclientset import ( diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/doc.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/doc.go index 22ccee919..b667dd515 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/doc.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - // This package has the automatically generated clientset. package internalclientset diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/fake/clientset_generated.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/fake/clientset_generated.go index 3c0f41dba..fdc0beee5 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/fake/clientset_generated.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/fake/clientset_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - package fake import ( @@ -43,15 +41,7 @@ func NewSimpleClientset(objects ...runtime.Object) *Clientset { fakePtr := testing.Fake{} fakePtr.AddReactor("*", "*", testing.ObjectReaction(o)) - fakePtr.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) { - gvr := action.GetResource() - ns := action.GetNamespace() - watch, err := o.Watch(gvr, ns) - if err != nil { - return false, nil, err - } - return true, watch, nil - }) + fakePtr.AddWatchReactor("*", testing.DefaultWatchReactor(watch.NewFake(), nil)) return &Clientset{fakePtr, &fakediscovery.FakeDiscovery{Fake: &fakePtr}} } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/fake/doc.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/fake/doc.go index 0bc260bca..3fd8e1e2c 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/fake/doc.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/fake/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - // This package has the automatically generated fake clientset. package fake diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/fake/register.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/fake/register.go index 5c17a1003..1ebf1f9d0 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/fake/register.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/fake/register.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - package fake import ( @@ -40,7 +38,7 @@ func init() { // // import ( // "k8s.io/client-go/kubernetes" -// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// clientsetscheme "k8s.io/client-go/kuberentes/scheme" // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" // ) // @@ -51,4 +49,5 @@ func init() { // correctly. func AddToScheme(scheme *runtime.Scheme) { apiextensionsinternalversion.AddToScheme(scheme) + } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/scheme/doc.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/scheme/doc.go index 5c5c8debb..3ec2200d0 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/scheme/doc.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/scheme/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - // This package contains the scheme of the automatically generated clientset. package scheme diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/scheme/register.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/scheme/register.go index f9de21961..92e65a67d 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/scheme/register.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/scheme/register.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,13 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - package scheme import ( - os "os" - apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install" announced "k8s.io/apimachinery/pkg/apimachinery/announced" registered "k8s.io/apimachinery/pkg/apimachinery/registered" @@ -28,6 +24,7 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" serializer "k8s.io/apimachinery/pkg/runtime/serializer" + os "os" ) var Scheme = runtime.NewScheme() @@ -45,4 +42,5 @@ func init() { // Install registers the API group and adds types to a scheme func Install(groupFactoryRegistry announced.APIGroupFactoryRegistry, registry *registered.APIRegistrationManager, scheme *runtime.Scheme) { apiextensions.Install(groupFactoryRegistry, registry, scheme) + } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/apiextensions_client.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/apiextensions_client.go index 9e08a905a..288908679 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/apiextensions_client.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/apiextensions_client.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - package internalversion import ( diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/customresourcedefinition.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/customresourcedefinition.go index 322454cdf..7758b635f 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/customresourcedefinition.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/customresourcedefinition.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - package internalversion import ( diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/doc.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/doc.go index b057e5201..3adf06d89 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/doc.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - // This package has the automatically generated typed clients. package internalversion diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/fake/doc.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/fake/doc.go index 87a1873ed..c58fac35e 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/fake/doc.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/fake/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - // Package fake has the automatically generated clients. package fake diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/fake/fake_apiextensions_client.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/fake/fake_apiextensions_client.go index 32bb913c0..e90e8c6b4 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/fake/fake_apiextensions_client.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/fake/fake_apiextensions_client.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - package fake import ( diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/fake/fake_customresourcedefinition.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/fake/fake_customresourcedefinition.go index c5cd1da48..6cf8f7e7d 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/fake/fake_customresourcedefinition.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/fake/fake_customresourcedefinition.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - package fake import ( diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/generated_expansion.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/generated_expansion.go index 74c295f6c..b1721b0d0 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/generated_expansion.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset/typed/apiextensions/internalversion/generated_expansion.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by client-gen. DO NOT EDIT. - package internalversion type CustomResourceDefinitionExpansion interface{} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/interface.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/interface.go index e88c53087..e1ad6afcc 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/interface.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by informer-gen. DO NOT EDIT. +// This file was automatically generated by informer-gen package apiextensions diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1beta1/customresourcedefinition.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1beta1/customresourcedefinition.go index 9d9b12787..cc86c42e9 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1beta1/customresourcedefinition.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1beta1/customresourcedefinition.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,13 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by informer-gen. DO NOT EDIT. +// This file was automatically generated by informer-gen package v1beta1 import ( - time "time" - apiextensions_v1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" clientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" internalinterfaces "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/internalinterfaces" @@ -29,6 +27,7 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" + time "time" ) // CustomResourceDefinitionInformer provides access to a shared informer and lister for diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1beta1/interface.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1beta1/interface.go index 331dad83e..2a5827026 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1beta1/interface.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1beta1/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by informer-gen. DO NOT EDIT. +// This file was automatically generated by informer-gen package v1beta1 diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/factory.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/factory.go index 6e7141621..fbaa2c65d 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/factory.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/factory.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,15 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by informer-gen. DO NOT EDIT. +// This file was automatically generated by informer-gen package externalversions import ( - reflect "reflect" - sync "sync" - time "time" - clientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" apiextensions "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions" internalinterfaces "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/internalinterfaces" @@ -30,6 +26,9 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" + reflect "reflect" + sync "sync" + time "time" ) type sharedInformerFactory struct { diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/generic.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/generic.go index a742bbd25..059fd5724 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/generic.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/generic.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,13 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by informer-gen. DO NOT EDIT. +// This file was automatically generated by informer-gen package externalversions import ( "fmt" - v1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go index 2048b744f..80b53e772 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,17 +14,16 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by informer-gen. DO NOT EDIT. +// This file was automatically generated by informer-gen package internalinterfaces import ( - time "time" - clientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" cache "k8s.io/client-go/tools/cache" + time "time" ) type NewInformerFunc func(clientset.Interface, time.Duration) cache.SharedIndexInformer diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/interface.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/interface.go index f096df135..e422eb440 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/interface.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by informer-gen. DO NOT EDIT. +// This file was automatically generated by informer-gen package apiextensions diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion/customresourcedefinition.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion/customresourcedefinition.go index 08587b732..20c863125 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion/customresourcedefinition.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion/customresourcedefinition.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,13 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by informer-gen. DO NOT EDIT. +// This file was automatically generated by informer-gen package internalversion import ( - time "time" - apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" internalclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset" internalinterfaces "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/internalinterfaces" @@ -29,6 +27,7 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" cache "k8s.io/client-go/tools/cache" + time "time" ) // CustomResourceDefinitionInformer provides access to a shared informer and lister for diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion/interface.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion/interface.go index 15c7e9f14..4183e973d 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion/interface.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions/internalversion/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by informer-gen. DO NOT EDIT. +// This file was automatically generated by informer-gen package internalversion diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/factory.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/factory.go index b1d07527d..ee83d6dfc 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/factory.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/factory.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,15 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by informer-gen. DO NOT EDIT. +// This file was automatically generated by informer-gen package internalversion import ( - reflect "reflect" - sync "sync" - time "time" - internalclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset" apiextensions "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/apiextensions" internalinterfaces "k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/internalinterfaces" @@ -30,6 +26,9 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" + reflect "reflect" + sync "sync" + time "time" ) type sharedInformerFactory struct { diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/generic.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/generic.go index 77a9e1b0b..4a013283a 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/generic.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/generic.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,13 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by informer-gen. DO NOT EDIT. +// This file was automatically generated by informer-gen package internalversion import ( "fmt" - apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/internalinterfaces/factory_interfaces.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/internalinterfaces/factory_interfaces.go index d41da2418..e93f43f50 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/internalinterfaces/factory_interfaces.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/informers/internalversion/internalinterfaces/factory_interfaces.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,17 +14,16 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by informer-gen. DO NOT EDIT. +// This file was automatically generated by informer-gen package internalinterfaces import ( - time "time" - internalclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/internalclientset" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" cache "k8s.io/client-go/tools/cache" + time "time" ) type NewInformerFunc func(internalclientset.Interface, time.Duration) cache.SharedIndexInformer diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion/customresourcedefinition.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion/customresourcedefinition.go index c736b3db8..1bd848051 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion/customresourcedefinition.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion/customresourcedefinition.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by lister-gen. DO NOT EDIT. +// This file was automatically generated by lister-gen package internalversion diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion/expansion_generated.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion/expansion_generated.go index 05a413aee..3be1e9164 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion/expansion_generated.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion/expansion_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by lister-gen. DO NOT EDIT. +// This file was automatically generated by lister-gen package internalversion diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1/customresourcedefinition.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1/customresourcedefinition.go index 468f5a664..316721bd6 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1/customresourcedefinition.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1/customresourcedefinition.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by lister-gen. DO NOT EDIT. +// This file was automatically generated by lister-gen package v1beta1 diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1/expansion_generated.go b/vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1/expansion_generated.go index 65b786659..5723fc39b 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1/expansion_generated.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1/expansion_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Kubernetes Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Code generated by lister-gen. DO NOT EDIT. +// This file was automatically generated by lister-gen package v1beta1 diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/cmd/server/start.go b/vendor/k8s.io/apiextensions-apiserver/pkg/cmd/server/start.go index df3cf3e60..6b41a2e06 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/cmd/server/start.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/cmd/server/start.go @@ -36,7 +36,6 @@ const defaultEtcdPathPrefix = "/registry/apiextensions.kubernetes.io" type CustomResourceDefinitionsServerOptions struct { RecommendedOptions *genericoptions.RecommendedOptions - APIEnablement *genericoptions.APIEnablementOptions StdOut io.Writer StdErr io.Writer @@ -45,7 +44,6 @@ type CustomResourceDefinitionsServerOptions struct { func NewCustomResourceDefinitionsServerOptions(out, errOut io.Writer) *CustomResourceDefinitionsServerOptions { o := &CustomResourceDefinitionsServerOptions{ RecommendedOptions: genericoptions.NewRecommendedOptions(defaultEtcdPathPrefix, apiserver.Codecs.LegacyCodec(v1beta1.SchemeGroupVersion)), - APIEnablement: genericoptions.NewAPIEnablementOptions(), StdOut: out, StdErr: errOut, @@ -79,14 +77,13 @@ func NewCommandStartCustomResourceDefinitionsServer(out, errOut io.Writer, stopC flags := cmd.Flags() o.RecommendedOptions.AddFlags(flags) - o.APIEnablement.AddFlags(flags) + return cmd } func (o CustomResourceDefinitionsServerOptions) Validate(args []string) error { errors := []error{} errors = append(errors, o.RecommendedOptions.Validate()...) - errors = append(errors, o.APIEnablement.Validate(apiserver.Registry)...) return utilerrors.NewAggregate(errors) } @@ -101,10 +98,7 @@ func (o CustomResourceDefinitionsServerOptions) Config() (*apiserver.Config, err } serverConfig := genericapiserver.NewRecommendedConfig(apiserver.Codecs) - if err := o.RecommendedOptions.ApplyTo(serverConfig, apiserver.Scheme); err != nil { - return nil, err - } - if err := o.APIEnablement.ApplyTo(&serverConfig.Config, apiserver.DefaultAPIResourceConfigSource(), apiserver.Registry); err != nil { + if err := o.RecommendedOptions.ApplyTo(serverConfig); err != nil { return nil, err } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/controller/finalizer/crd_finalizer.go b/vendor/k8s.io/apiextensions-apiserver/pkg/controller/finalizer/crd_finalizer.go index f881427ef..b60900ab1 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/controller/finalizer/crd_finalizer.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/controller/finalizer/crd_finalizer.go @@ -65,7 +65,7 @@ type ListerCollectionDeleter interface { type CRClientGetter interface { // GetCustomResourceListerCollectionDeleter gets the ListerCollectionDeleter for the given CRD // UID. - GetCustomResourceListerCollectionDeleter(crd *apiextensions.CustomResourceDefinition) (ListerCollectionDeleter, error) + GetCustomResourceListerCollectionDeleter(crd *apiextensions.CustomResourceDefinition) ListerCollectionDeleter } // NewCRDFinalizer creates a new CRDFinalizer. @@ -155,9 +155,9 @@ func (c *CRDFinalizer) deleteInstances(crd *apiextensions.CustomResourceDefiniti // Now we can start deleting items. While it would be ideal to use a REST API client, doing so // could incorrectly delete a ThirdPartyResource with the same URL as the CustomResource, so we go // directly to the storage instead. Since we control the storage, we know that delete collection works. - crClient, err := c.crClientGetter.GetCustomResourceListerCollectionDeleter(crd) - if err != nil { - err = fmt.Errorf("unable to find a custom resource client for %s.%s: %v", crd.Status.AcceptedNames.Plural, crd.Spec.Group, err) + crClient := c.crClientGetter.GetCustomResourceListerCollectionDeleter(crd) + if crClient == nil { + err := fmt.Errorf("unable to find a custom resource client for %s.%s", crd.Status.AcceptedNames.Plural, crd.Spec.Group) return apiextensions.CustomResourceDefinitionCondition{ Type: apiextensions.Terminating, Status: apiextensions.ConditionTrue, diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/controller/status/BUILD b/vendor/k8s.io/apiextensions-apiserver/pkg/controller/status/BUILD index c408cf487..2abd62ff1 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/controller/status/BUILD +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/controller/status/BUILD @@ -9,7 +9,8 @@ load( go_test( name = "go_default_test", srcs = ["naming_controller_test.go"], - embed = [":go_default_library"], + importpath = "k8s.io/apiextensions-apiserver/pkg/controller/status", + library = ":go_default_library", deps = [ "//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library", "//vendor/k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/internalversion:go_default_library", diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/controller/status/naming_controller.go b/vendor/k8s.io/apiextensions-apiserver/pkg/controller/status/naming_controller.go index 16016e493..c0a7cc86f 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/controller/status/naming_controller.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/controller/status/naming_controller.go @@ -182,8 +182,6 @@ func (c *NamingConditionController) calculateNamesAndConditions(in *apiextension newNames.ListKind = requestedNames.ListKind } - newNames.Categories = requestedNames.Categories - // if we haven't changed the condition, then our names must be good. if namesAcceptedCondition.Status == apiextensions.ConditionUnknown { namesAcceptedCondition.Status = apiextensions.ConditionTrue diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go b/vendor/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go index b80e80ac3..80b37bf7b 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go @@ -33,12 +33,6 @@ const ( // // CustomResourceValidation is a list of validation methods for CustomResources CustomResourceValidation utilfeature.Feature = "CustomResourceValidation" - - // owner: @sttts, @nikhita - // alpha: v1.10 - // - // CustomResourceSubresources defines the subresources for CustomResources - CustomResourceSubresources utilfeature.Feature = "CustomResourceSubresources" ) func init() { @@ -49,6 +43,5 @@ func init() { // To add a new feature, define a key for it above and add it here. The features will be // available throughout Kubernetes binaries. var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureSpec{ - CustomResourceValidation: {Default: true, PreRelease: utilfeature.Beta}, - CustomResourceSubresources: {Default: false, PreRelease: utilfeature.Alpha}, + CustomResourceValidation: {Default: true, PreRelease: utilfeature.Beta}, } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/BUILD b/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/BUILD index 73ac1009e..84d77bd5b 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/BUILD +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/BUILD @@ -3,30 +3,20 @@ package(default_visibility = ["//visibility:public"]) load( "@io_bazel_rules_go//go:def.bzl", "go_library", - "go_test", ) go_library( name = "go_default_library", srcs = [ "etcd.go", - "registry.go", - "status_strategy.go", "strategy.go", - "validator.go", ], importpath = "k8s.io/apiextensions-apiserver/pkg/registry/customresource", deps = [ "//vendor/github.com/go-openapi/validate:go_default_library", - "//vendor/k8s.io/api/autoscaling/v1:go_default_library", - "//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library", "//vendor/k8s.io/apiextensions-apiserver/pkg/apiserver/validation:go_default_library", - "//vendor/k8s.io/apiextensions-apiserver/pkg/features:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/validation:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library", "//vendor/k8s.io/apimachinery/pkg/fields:go_default_library", @@ -34,14 +24,11 @@ go_library( "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/watch:go_default_library", "//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library", "//vendor/k8s.io/apiserver/pkg/registry/generic:go_default_library", "//vendor/k8s.io/apiserver/pkg/registry/generic/registry:go_default_library", - "//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library", "//vendor/k8s.io/apiserver/pkg/storage:go_default_library", "//vendor/k8s.io/apiserver/pkg/storage/names:go_default_library", - "//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library", ], ) @@ -54,34 +41,6 @@ filegroup( filegroup( name = "all-srcs", - srcs = [ - ":package-srcs", - "//staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor:all-srcs", - ], + srcs = [":package-srcs"], tags = ["automanaged"], ) - -go_test( - name = "go_default_xtest", - srcs = ["etcd_test.go"], - deps = [ - "//vendor/k8s.io/api/autoscaling/v1:go_default_library", - "//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions:go_default_library", - "//vendor/k8s.io/apiextensions-apiserver/pkg/apiserver:go_default_library", - "//vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource:go_default_library", - "//vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library", - "//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library", - "//vendor/k8s.io/apiserver/pkg/registry/generic:go_default_library", - "//vendor/k8s.io/apiserver/pkg/registry/generic/testing:go_default_library", - "//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library", - "//vendor/k8s.io/apiserver/pkg/storage/etcd/testing:go_default_library", - "//vendor/k8s.io/client-go/discovery:go_default_library", - ], -) diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd.go b/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd.go index bf54fe33b..0cbf3b112 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd.go @@ -17,65 +17,20 @@ limitations under the License. package customresource import ( - "fmt" - "strings" - - autoscalingv1 "k8s.io/api/autoscaling/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/registry/generic" genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" - "k8s.io/apiserver/pkg/registry/rest" ) -// CustomResourceStorage includes dummy storage for CustomResources, and their Status and Scale subresources. -type CustomResourceStorage struct { - CustomResource *REST - Status *StatusREST - Scale *ScaleREST -} - -func NewStorage(resource schema.GroupResource, listKind schema.GroupVersionKind, strategy customResourceStrategy, optsGetter generic.RESTOptionsGetter, categories []string, tableConvertor rest.TableConvertor) CustomResourceStorage { - customResourceREST, customResourceStatusREST := newREST(resource, listKind, strategy, optsGetter, categories, tableConvertor) - customResourceRegistry := NewRegistry(customResourceREST) - - s := CustomResourceStorage{ - CustomResource: customResourceREST, - } - - if strategy.status != nil { - s.Status = customResourceStatusREST - } - - if scale := strategy.scale; scale != nil { - var labelSelectorPath string - if scale.LabelSelectorPath != nil { - labelSelectorPath = *scale.LabelSelectorPath - } - - s.Scale = &ScaleREST{ - registry: customResourceRegistry, - specReplicasPath: scale.SpecReplicasPath, - statusReplicasPath: scale.StatusReplicasPath, - labelSelectorPath: labelSelectorPath, - } - } - - return s -} - // REST implements a RESTStorage for API services against etcd type REST struct { *genericregistry.Store - categories []string } -// newREST returns a RESTStorage object that will work against API services. -func newREST(resource schema.GroupResource, listKind schema.GroupVersionKind, strategy customResourceStrategy, optsGetter generic.RESTOptionsGetter, categories []string, tableConvertor rest.TableConvertor) (*REST, *StatusREST) { +// NewREST returns a RESTStorage object that will work against API services. +func NewREST(resource schema.GroupResource, listKind schema.GroupVersionKind, strategy customResourceDefinitionStorageStrategy, optsGetter generic.RESTOptionsGetter) *REST { store := &genericregistry.Store{ NewFunc: func() runtime.Object { return &unstructured.Unstructured{} }, NewListFunc: func() runtime.Object { @@ -90,176 +45,10 @@ func newREST(resource schema.GroupResource, listKind schema.GroupVersionKind, st CreateStrategy: strategy, UpdateStrategy: strategy, DeleteStrategy: strategy, - - TableConvertor: tableConvertor, } options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: strategy.GetAttrs} if err := store.CompleteWithOptions(options); err != nil { panic(err) // TODO: Propagate error up } - - statusStore := *store - statusStore.UpdateStrategy = NewStatusStrategy(strategy) - return &REST{store, categories}, &StatusREST{store: &statusStore} -} - -// Implement CategoriesProvider -var _ rest.CategoriesProvider = &REST{} - -// Categories implements the CategoriesProvider interface. Returns a list of categories a resource is part of. -func (r *REST) Categories() []string { - return r.categories -} - -// StatusREST implements the REST endpoint for changing the status of a CustomResource -type StatusREST struct { - store *genericregistry.Store -} - -func (r *StatusREST) New() runtime.Object { - return &unstructured.Unstructured{} -} - -// Get retrieves the object from the storage. It is required to support Patch. -func (r *StatusREST) Get(ctx genericapirequest.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { - return r.store.Get(ctx, name, options) -} - -// Update alters the status subset of an object. -func (r *StatusREST) Update(ctx genericapirequest.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (runtime.Object, bool, error) { - return r.store.Update(ctx, name, objInfo, createValidation, updateValidation) -} - -type ScaleREST struct { - registry Registry - specReplicasPath string - statusReplicasPath string - labelSelectorPath string -} - -// ScaleREST implements Patcher -var _ = rest.Patcher(&ScaleREST{}) -var _ = rest.GroupVersionKindProvider(&ScaleREST{}) - -func (r *ScaleREST) GroupVersionKind(containingGV schema.GroupVersion) schema.GroupVersionKind { - return autoscalingv1.SchemeGroupVersion.WithKind("Scale") -} - -// New creates a new Scale object -func (r *ScaleREST) New() runtime.Object { - return &autoscalingv1.Scale{} -} - -func (r *ScaleREST) Get(ctx genericapirequest.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { - cr, err := r.registry.GetCustomResource(ctx, name, options) - if err != nil { - return nil, err - } - - scaleObject, replicasFound, err := scaleFromCustomResource(cr, r.specReplicasPath, r.statusReplicasPath, r.labelSelectorPath) - if err != nil { - return nil, err - } - if !replicasFound { - return nil, apierrors.NewInternalError(fmt.Errorf("the spec replicas field %q does not exist", r.specReplicasPath)) - } - return scaleObject, err -} - -func (r *ScaleREST) Update(ctx genericapirequest.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (runtime.Object, bool, error) { - cr, err := r.registry.GetCustomResource(ctx, name, &metav1.GetOptions{}) - if err != nil { - return nil, false, err - } - - const invalidSpecReplicas = -2147483648 // smallest int32 - oldScale, replicasFound, err := scaleFromCustomResource(cr, r.specReplicasPath, r.statusReplicasPath, r.labelSelectorPath) - if err != nil { - return nil, false, err - } - if !replicasFound { - oldScale.Spec.Replicas = invalidSpecReplicas // signal that this was not set before - } - - obj, err := objInfo.UpdatedObject(ctx, oldScale) - if err != nil { - return nil, false, err - } - if obj == nil { - return nil, false, apierrors.NewBadRequest(fmt.Sprintf("nil update passed to Scale")) - } - - scale, ok := obj.(*autoscalingv1.Scale) - if !ok { - return nil, false, apierrors.NewBadRequest(fmt.Sprintf("wrong object passed to Scale update: %v", obj)) - } - - if scale.Spec.Replicas == invalidSpecReplicas { - return nil, false, apierrors.NewBadRequest(fmt.Sprintf("the spec replicas field %q cannot be empty", r.specReplicasPath)) - } - - specReplicasPath := strings.TrimPrefix(r.specReplicasPath, ".") // ignore leading period - if err = unstructured.SetNestedField(cr.Object, int64(scale.Spec.Replicas), strings.Split(specReplicasPath, ".")...); err != nil { - return nil, false, err - } - cr.SetResourceVersion(scale.ResourceVersion) - - cr, err = r.registry.UpdateCustomResource(ctx, cr, createValidation, updateValidation) - if err != nil { - return nil, false, err - } - - newScale, _, err := scaleFromCustomResource(cr, r.specReplicasPath, r.statusReplicasPath, r.labelSelectorPath) - if err != nil { - return nil, false, apierrors.NewBadRequest(err.Error()) - } - return newScale, false, err -} - -// scaleFromCustomResource returns a scale subresource for a customresource and a bool signalling wether -// the specReplicas value was found. -func scaleFromCustomResource(cr *unstructured.Unstructured, specReplicasPath, statusReplicasPath, labelSelectorPath string) (*autoscalingv1.Scale, bool, error) { - specReplicasPath = strings.TrimPrefix(specReplicasPath, ".") // ignore leading period - specReplicas, foundSpecReplicas, err := unstructured.NestedInt64(cr.UnstructuredContent(), strings.Split(specReplicasPath, ".")...) - if err != nil { - return nil, false, err - } else if !foundSpecReplicas { - specReplicas = 0 - } - - statusReplicasPath = strings.TrimPrefix(statusReplicasPath, ".") // ignore leading period - statusReplicas, found, err := unstructured.NestedInt64(cr.UnstructuredContent(), strings.Split(statusReplicasPath, ".")...) - if err != nil { - return nil, false, err - } else if !found { - statusReplicas = 0 - } - - var labelSelector string - if len(labelSelectorPath) > 0 { - labelSelectorPath = strings.TrimPrefix(labelSelectorPath, ".") // ignore leading period - labelSelector, found, err = unstructured.NestedString(cr.UnstructuredContent(), strings.Split(labelSelectorPath, ".")...) - if err != nil { - return nil, false, err - } - } - - scale := &autoscalingv1.Scale{ - ObjectMeta: metav1.ObjectMeta{ - Name: cr.GetName(), - Namespace: cr.GetNamespace(), - UID: cr.GetUID(), - ResourceVersion: cr.GetResourceVersion(), - CreationTimestamp: cr.GetCreationTimestamp(), - }, - Spec: autoscalingv1.ScaleSpec{ - Replicas: int32(specReplicas), - }, - Status: autoscalingv1.ScaleStatus{ - Replicas: int32(statusReplicas), - Selector: labelSelector, - }, - } - - return scale, foundSpecReplicas, nil + return &REST{store} } diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd_test.go b/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd_test.go deleted file mode 100644 index 8bee3396c..000000000 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd_test.go +++ /dev/null @@ -1,400 +0,0 @@ -/* -Copyright 2018 The Kubernetes 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 customresource_test - -import ( - "io" - "reflect" - "strings" - "testing" - - autoscalingv1 "k8s.io/api/autoscaling/v1" - apiequality "k8s.io/apimachinery/pkg/api/equality" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/diff" - genericapirequest "k8s.io/apiserver/pkg/endpoints/request" - "k8s.io/apiserver/pkg/registry/generic" - registrytest "k8s.io/apiserver/pkg/registry/generic/testing" - "k8s.io/apiserver/pkg/registry/rest" - etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing" - "k8s.io/client-go/discovery" - - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" - "k8s.io/apiextensions-apiserver/pkg/apiserver" - "k8s.io/apiextensions-apiserver/pkg/registry/customresource" - "k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor" -) - -func newStorage(t *testing.T) (customresource.CustomResourceStorage, *etcdtesting.EtcdTestServer) { - server, etcdStorage := etcdtesting.NewUnsecuredEtcd3TestClientServer(t) - etcdStorage.Codec = unstructuredJsonCodec{} - restOptions := generic.RESTOptions{StorageConfig: etcdStorage, Decorator: generic.UndecoratedStorage, DeleteCollectionWorkers: 1, ResourcePrefix: "noxus"} - - parameterScheme := runtime.NewScheme() - parameterScheme.AddUnversionedTypes(schema.GroupVersion{Group: "mygroup.example.com", Version: "v1beta1"}, - &metav1.ListOptions{}, - &metav1.ExportOptions{}, - &metav1.GetOptions{}, - &metav1.DeleteOptions{}, - ) - - typer := apiserver.UnstructuredObjectTyper{ - Delegate: parameterScheme, - UnstructuredTyper: discovery.NewUnstructuredObjectTyper(nil), - } - - kind := schema.GroupVersionKind{Group: "mygroup.example.com", Version: "v1beta1", Kind: "Noxu"} - - labelSelectorPath := ".status.labelSelector" - scale := &apiextensions.CustomResourceSubresourceScale{ - SpecReplicasPath: ".spec.replicas", - StatusReplicasPath: ".status.replicas", - LabelSelectorPath: &labelSelectorPath, - } - - status := &apiextensions.CustomResourceSubresourceStatus{} - - // TODO: identify how to pass printer specification from the CRD - table, _ := tableconvertor.New(nil) - - storage := customresource.NewStorage( - schema.GroupResource{Group: "mygroup.example.com", Resource: "noxus"}, - schema.GroupVersionKind{Group: "mygroup.example.com", Version: "v1beta1", Kind: "NoxuItemList"}, - customresource.NewStrategy( - typer, - true, - kind, - nil, - nil, - status, - scale, - ), - restOptions, - []string{"all"}, - table, - ) - - return storage, server -} - -// createCustomResource is a helper function that returns a CustomResource with the updated resource version. -func createCustomResource(storage *customresource.REST, cr unstructured.Unstructured, t *testing.T) (unstructured.Unstructured, error) { - ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), cr.GetNamespace()) - obj, err := storage.Create(ctx, &cr, rest.ValidateAllObjectFunc, false) - if err != nil { - t.Errorf("Failed to create CustomResource, %v", err) - } - newCR := obj.(*unstructured.Unstructured) - return *newCR, nil -} - -func validNewCustomResource() *unstructured.Unstructured { - return &unstructured.Unstructured{ - Object: map[string]interface{}{ - "apiVersion": "mygroup.example.com/v1beta1", - "kind": "Noxu", - "metadata": map[string]interface{}{ - "namespace": "default", - "name": "foo", - }, - "spec": map[string]interface{}{ - "replicas": int64(7), - }, - }, - } -} - -var validCustomResource = *validNewCustomResource() - -func TestCreate(t *testing.T) { - storage, server := newStorage(t) - defer server.Terminate(t) - defer storage.CustomResource.Store.DestroyFunc() - test := registrytest.New(t, storage.CustomResource.Store) - cr := validNewCustomResource() - cr.SetNamespace("") - test.TestCreate( - cr, - ) -} - -func TestGet(t *testing.T) { - storage, server := newStorage(t) - defer server.Terminate(t) - defer storage.CustomResource.Store.DestroyFunc() - test := registrytest.New(t, storage.CustomResource.Store) - test.TestGet(validNewCustomResource()) -} - -func TestList(t *testing.T) { - storage, server := newStorage(t) - defer server.Terminate(t) - defer storage.CustomResource.Store.DestroyFunc() - test := registrytest.New(t, storage.CustomResource.Store) - test.TestList(validNewCustomResource()) -} - -func TestDelete(t *testing.T) { - storage, server := newStorage(t) - defer server.Terminate(t) - defer storage.CustomResource.Store.DestroyFunc() - test := registrytest.New(t, storage.CustomResource.Store) - test.TestDelete(validNewCustomResource()) -} - -func TestCategories(t *testing.T) { - storage, server := newStorage(t) - defer server.Terminate(t) - defer storage.CustomResource.Store.DestroyFunc() - - expected := []string{"all"} - actual := storage.CustomResource.Categories() - ok := reflect.DeepEqual(actual, expected) - if !ok { - t.Errorf("categories are not equal. expected = %v actual = %v", expected, actual) - } -} - -func TestStatusUpdate(t *testing.T) { - storage, server := newStorage(t) - defer server.Terminate(t) - defer storage.CustomResource.Store.DestroyFunc() - ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), metav1.NamespaceDefault) - key := "/noxus/" + metav1.NamespaceDefault + "/foo" - validCustomResource := validNewCustomResource() - if err := storage.CustomResource.Storage.Create(ctx, key, validCustomResource, nil, 0); err != nil { - t.Fatalf("unexpected error: %v", err) - } - - gottenObj, err := storage.CustomResource.Get(ctx, "foo", &metav1.GetOptions{}) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - update := gottenObj.(*unstructured.Unstructured) - updateContent := update.Object - updateContent["status"] = map[string]interface{}{ - "replicas": int64(7), - } - - if _, _, err := storage.Status.Update(ctx, update.GetName(), rest.DefaultUpdatedObjectInfo(update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc); err != nil { - t.Fatalf("unexpected error: %v", err) - } - - obj, err := storage.CustomResource.Get(ctx, "foo", &metav1.GetOptions{}) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - cr, ok := obj.(*unstructured.Unstructured) - if !ok { - t.Fatal("unexpected error: custom resource should be of type Unstructured") - } - content := cr.UnstructuredContent() - - spec := content["spec"].(map[string]interface{}) - status := content["status"].(map[string]interface{}) - - if spec["replicas"].(int64) != 7 { - t.Errorf("we expected .spec.replicas to not be updated but it was updated to %v", spec["replicas"].(int64)) - } - if status["replicas"].(int64) != 7 { - t.Errorf("we expected .status.replicas to be updated to %d but it was %v", 7, status["replicas"].(int64)) - } -} - -func TestScaleGet(t *testing.T) { - storage, server := newStorage(t) - defer server.Terminate(t) - defer storage.CustomResource.Store.DestroyFunc() - - name := "foo" - - var cr unstructured.Unstructured - ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), metav1.NamespaceDefault) - key := "/noxus/" + metav1.NamespaceDefault + "/" + name - if err := storage.CustomResource.Storage.Create(ctx, key, &validCustomResource, &cr, 0); err != nil { - t.Fatalf("error setting new custom resource (key: %s) %v: %v", key, validCustomResource, err) - } - - want := &autoscalingv1.Scale{ - ObjectMeta: metav1.ObjectMeta{ - Name: cr.GetName(), - Namespace: metav1.NamespaceDefault, - UID: cr.GetUID(), - ResourceVersion: cr.GetResourceVersion(), - CreationTimestamp: cr.GetCreationTimestamp(), - }, - Spec: autoscalingv1.ScaleSpec{ - Replicas: int32(7), - }, - } - - obj, err := storage.Scale.Get(ctx, name, &metav1.GetOptions{}) - if err != nil { - t.Fatalf("error fetching scale for %s: %v", name, err) - } - - got := obj.(*autoscalingv1.Scale) - if !apiequality.Semantic.DeepEqual(got, want) { - t.Errorf("unexpected scale: %s", diff.ObjectDiff(got, want)) - } -} - -func TestScaleGetWithoutSpecReplicas(t *testing.T) { - storage, server := newStorage(t) - defer server.Terminate(t) - defer storage.CustomResource.Store.DestroyFunc() - - name := "foo" - - var cr unstructured.Unstructured - ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), metav1.NamespaceDefault) - key := "/noxus/" + metav1.NamespaceDefault + "/" + name - withoutSpecReplicas := validCustomResource.DeepCopy() - unstructured.RemoveNestedField(withoutSpecReplicas.Object, "spec", "replicas") - if err := storage.CustomResource.Storage.Create(ctx, key, withoutSpecReplicas, &cr, 0); err != nil { - t.Fatalf("error setting new custom resource (key: %s) %v: %v", key, withoutSpecReplicas, err) - } - - _, err := storage.Scale.Get(ctx, name, &metav1.GetOptions{}) - if err == nil { - t.Fatalf("error expected for %s", name) - } - if expected := `the spec replicas field ".spec.replicas" does not exist`; !strings.Contains(err.Error(), expected) { - t.Fatalf("expected error string %q, got: %v", expected, err) - } -} - -func TestScaleUpdate(t *testing.T) { - storage, server := newStorage(t) - defer server.Terminate(t) - defer storage.CustomResource.Store.DestroyFunc() - - name := "foo" - - var cr unstructured.Unstructured - ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), metav1.NamespaceDefault) - key := "/noxus/" + metav1.NamespaceDefault + "/" + name - if err := storage.CustomResource.Storage.Create(ctx, key, &validCustomResource, &cr, 0); err != nil { - t.Fatalf("error setting new custom resource (key: %s) %v: %v", key, validCustomResource, err) - } - - obj, err := storage.Scale.Get(ctx, name, &metav1.GetOptions{}) - if err != nil { - t.Fatalf("error fetching scale for %s: %v", name, err) - } - scale, ok := obj.(*autoscalingv1.Scale) - if !ok { - t.Fatalf("%v is not of the type autoscalingv1.Scale", scale) - } - - replicas := 12 - update := autoscalingv1.Scale{ - ObjectMeta: scale.ObjectMeta, - Spec: autoscalingv1.ScaleSpec{ - Replicas: int32(replicas), - }, - } - - if _, _, err := storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc); err != nil { - t.Fatalf("error updating scale %v: %v", update, err) - } - - obj, err = storage.Scale.Get(ctx, name, &metav1.GetOptions{}) - if err != nil { - t.Fatalf("error fetching scale for %s: %v", name, err) - } - scale = obj.(*autoscalingv1.Scale) - if scale.Spec.Replicas != int32(replicas) { - t.Errorf("wrong replicas count: expected: %d got: %d", replicas, scale.Spec.Replicas) - } - - update.ResourceVersion = scale.ResourceVersion - update.Spec.Replicas = 15 - - if _, _, err = storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc); err != nil && !errors.IsConflict(err) { - t.Fatalf("unexpected error, expecting an update conflict but got %v", err) - } -} - -func TestScaleUpdateWithoutSpecReplicas(t *testing.T) { - storage, server := newStorage(t) - defer server.Terminate(t) - defer storage.CustomResource.Store.DestroyFunc() - - name := "foo" - - var cr unstructured.Unstructured - ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), metav1.NamespaceDefault) - key := "/noxus/" + metav1.NamespaceDefault + "/" + name - withoutSpecReplicas := validCustomResource.DeepCopy() - unstructured.RemoveNestedField(withoutSpecReplicas.Object, "spec", "replicas") - if err := storage.CustomResource.Storage.Create(ctx, key, withoutSpecReplicas, &cr, 0); err != nil { - t.Fatalf("error setting new custom resource (key: %s) %v: %v", key, withoutSpecReplicas, err) - } - - replicas := 12 - update := autoscalingv1.Scale{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - ResourceVersion: cr.GetResourceVersion(), - }, - Spec: autoscalingv1.ScaleSpec{ - Replicas: int32(replicas), - }, - } - - if _, _, err := storage.Scale.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc); err != nil { - t.Fatalf("error updating scale %v: %v", update, err) - } - - obj, err := storage.Scale.Get(ctx, name, &metav1.GetOptions{}) - if err != nil { - t.Fatalf("error fetching scale for %s: %v", name, err) - } - scale := obj.(*autoscalingv1.Scale) - if scale.Spec.Replicas != int32(replicas) { - t.Errorf("wrong replicas count: expected: %d got: %d", replicas, scale.Spec.Replicas) - } -} - -type unstructuredJsonCodec struct{} - -func (c unstructuredJsonCodec) Decode(data []byte, defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) { - obj := into.(*unstructured.Unstructured) - err := obj.UnmarshalJSON(data) - if err != nil { - return nil, nil, err - } - gvk := obj.GroupVersionKind() - return obj, &gvk, nil -} - -func (c unstructuredJsonCodec) Encode(obj runtime.Object, w io.Writer) error { - u := obj.(*unstructured.Unstructured) - bs, err := u.MarshalJSON() - if err != nil { - return err - } - w.Write(bs) - return nil -} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/registry.go b/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/registry.go deleted file mode 100644 index a0fd086d0..000000000 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/registry.go +++ /dev/null @@ -1,104 +0,0 @@ -/* -Copyright 2018 The Kubernetes 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 customresource - -import ( - "fmt" - "strings" - - "k8s.io/apimachinery/pkg/api/errors" - metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/watch" - genericapirequest "k8s.io/apiserver/pkg/endpoints/request" - "k8s.io/apiserver/pkg/registry/rest" -) - -// Registry is an interface for things that know how to store CustomResources. -type Registry interface { - ListCustomResources(ctx genericapirequest.Context, options *metainternalversion.ListOptions) (*unstructured.UnstructuredList, error) - WatchCustomResources(ctx genericapirequest.Context, options *metainternalversion.ListOptions) (watch.Interface, error) - GetCustomResource(ctx genericapirequest.Context, customResourceID string, options *metav1.GetOptions) (*unstructured.Unstructured, error) - CreateCustomResource(ctx genericapirequest.Context, customResource *unstructured.Unstructured, createValidation rest.ValidateObjectFunc) (*unstructured.Unstructured, error) - UpdateCustomResource(ctx genericapirequest.Context, customResource *unstructured.Unstructured, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (*unstructured.Unstructured, error) - DeleteCustomResource(ctx genericapirequest.Context, customResourceID string) error -} - -// storage puts strong typing around storage calls -type storage struct { - rest.StandardStorage -} - -// NewRegistry returns a new Registry interface for the given Storage. Any mismatched -// types will panic. -func NewRegistry(s rest.StandardStorage) Registry { - return &storage{s} -} - -func (s *storage) ListCustomResources(ctx genericapirequest.Context, options *metainternalversion.ListOptions) (*unstructured.UnstructuredList, error) { - if options != nil && options.FieldSelector != nil && !options.FieldSelector.Empty() { - return nil, fmt.Errorf("field selector not supported yet") - } - obj, err := s.List(ctx, options) - if err != nil { - return nil, err - } - return obj.(*unstructured.UnstructuredList), err -} - -func (s *storage) WatchCustomResources(ctx genericapirequest.Context, options *metainternalversion.ListOptions) (watch.Interface, error) { - return s.Watch(ctx, options) -} - -func (s *storage) GetCustomResource(ctx genericapirequest.Context, customResourceID string, options *metav1.GetOptions) (*unstructured.Unstructured, error) { - obj, err := s.Get(ctx, customResourceID, options) - customResource, ok := obj.(*unstructured.Unstructured) - if !ok { - return nil, fmt.Errorf("custom resource must be of type Unstructured") - } - - if err != nil { - apiVersion := customResource.GetAPIVersion() - groupVersion := strings.Split(apiVersion, "/") - group := groupVersion[0] - return nil, errors.NewNotFound(schema.GroupResource{Group: group, Resource: "scale"}, customResourceID) - } - return customResource, nil -} - -func (s *storage) CreateCustomResource(ctx genericapirequest.Context, customResource *unstructured.Unstructured, createValidation rest.ValidateObjectFunc) (*unstructured.Unstructured, error) { - obj, err := s.Create(ctx, customResource, rest.ValidateAllObjectFunc, false) - if err != nil { - return nil, err - } - return obj.(*unstructured.Unstructured), nil -} - -func (s *storage) UpdateCustomResource(ctx genericapirequest.Context, customResource *unstructured.Unstructured, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc) (*unstructured.Unstructured, error) { - obj, _, err := s.Update(ctx, customResource.GetName(), rest.DefaultUpdatedObjectInfo(customResource), createValidation, updateValidation) - if err != nil { - return nil, err - } - return obj.(*unstructured.Unstructured), nil -} - -func (s *storage) DeleteCustomResource(ctx genericapirequest.Context, customResourceID string) error { - _, _, err := s.Delete(ctx, customResourceID, nil) - return err -} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/status_strategy.go b/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/status_strategy.go deleted file mode 100644 index dab6bf47a..000000000 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/status_strategy.go +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright 2018 The Kubernetes 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 customresource - -import ( - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/validation/field" - genericapirequest "k8s.io/apiserver/pkg/endpoints/request" -) - -type statusStrategy struct { - customResourceStrategy -} - -func NewStatusStrategy(strategy customResourceStrategy) statusStrategy { - return statusStrategy{strategy} -} - -func (a statusStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object) { - newCustomResourceObject := obj.(*unstructured.Unstructured) - oldCustomResourceObject := old.(*unstructured.Unstructured) - - newCustomResource := newCustomResourceObject.UnstructuredContent() - oldCustomResource := oldCustomResourceObject.UnstructuredContent() - - // update is not allowed to set spec and metadata - _, ok1 := newCustomResource["spec"] - _, ok2 := oldCustomResource["spec"] - switch { - case ok2: - newCustomResource["spec"] = oldCustomResource["spec"] - case ok1: - delete(newCustomResource, "spec") - } - - newCustomResourceObject.SetAnnotations(oldCustomResourceObject.GetAnnotations()) - newCustomResourceObject.SetFinalizers(oldCustomResourceObject.GetFinalizers()) - newCustomResourceObject.SetGeneration(oldCustomResourceObject.GetGeneration()) - newCustomResourceObject.SetLabels(oldCustomResourceObject.GetLabels()) - newCustomResourceObject.SetOwnerReferences(oldCustomResourceObject.GetOwnerReferences()) - newCustomResourceObject.SetSelfLink(oldCustomResourceObject.GetSelfLink()) -} - -// ValidateUpdate is the default update validation for an end user updating status. -func (a statusStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList { - return a.customResourceStrategy.validator.ValidateStatusUpdate(ctx, obj, old, a.scale) -} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy.go b/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy.go index 092bfc89c..f001dc57a 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy.go @@ -17,10 +17,12 @@ limitations under the License. package customresource import ( + "fmt" + "github.com/go-openapi/validate" - apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/api/validation" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/fields" @@ -29,129 +31,63 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" - apiserverstorage "k8s.io/apiserver/pkg/storage" + "k8s.io/apiserver/pkg/storage" "k8s.io/apiserver/pkg/storage/names" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" - apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features" + apiservervalidation "k8s.io/apiextensions-apiserver/pkg/apiserver/validation" ) -// customResourceStrategy implements behavior for CustomResources. -type customResourceStrategy struct { +type customResourceDefinitionStorageStrategy struct { runtime.ObjectTyper names.NameGenerator namespaceScoped bool validator customResourceValidator - status *apiextensions.CustomResourceSubresourceStatus - scale *apiextensions.CustomResourceSubresourceScale } -func NewStrategy(typer runtime.ObjectTyper, namespaceScoped bool, kind schema.GroupVersionKind, schemaValidator, statusSchemaValidator *validate.SchemaValidator, status *apiextensions.CustomResourceSubresourceStatus, scale *apiextensions.CustomResourceSubresourceScale) customResourceStrategy { - return customResourceStrategy{ +func NewStrategy(typer runtime.ObjectTyper, namespaceScoped bool, kind schema.GroupVersionKind, validator *validate.SchemaValidator) customResourceDefinitionStorageStrategy { + return customResourceDefinitionStorageStrategy{ ObjectTyper: typer, NameGenerator: names.SimpleNameGenerator, namespaceScoped: namespaceScoped, - status: status, - scale: scale, validator: customResourceValidator{ - namespaceScoped: namespaceScoped, - kind: kind, - schemaValidator: schemaValidator, - statusSchemaValidator: statusSchemaValidator, + namespaceScoped: namespaceScoped, + kind: kind, + validator: validator, }, } } -func (a customResourceStrategy) NamespaceScoped() bool { +func (a customResourceDefinitionStorageStrategy) NamespaceScoped() bool { return a.namespaceScoped } -// PrepareForCreate clears the status of a CustomResource before creation. -func (a customResourceStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) { - if utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) && a.status != nil { - customResourceObject := obj.(*unstructured.Unstructured) - customResource := customResourceObject.UnstructuredContent() - - // create cannot set status - if _, ok := customResource["status"]; ok { - delete(customResource, "status") - } - } - - accessor, _ := meta.Accessor(obj) - accessor.SetGeneration(1) +func (customResourceDefinitionStorageStrategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) { } -// PrepareForUpdate clears fields that are not allowed to be set by end users on update. -func (a customResourceStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object) { - if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) || a.status == nil { - return - } - - newCustomResourceObject := obj.(*unstructured.Unstructured) - oldCustomResourceObject := old.(*unstructured.Unstructured) - - newCustomResource := newCustomResourceObject.UnstructuredContent() - oldCustomResource := oldCustomResourceObject.UnstructuredContent() - - // update is not allowed to set status - _, ok1 := newCustomResource["status"] - _, ok2 := oldCustomResource["status"] - switch { - case ok2: - newCustomResource["status"] = oldCustomResource["status"] - case ok1: - delete(newCustomResource, "status") - } - - // Any changes to the spec increment the generation number, any changes to the - // status should reflect the generation number of the corresponding object. We push - // the burden of managing the status onto the clients because we can't (in general) - // know here what version of spec the writer of the status has seen. It may seem like - // we can at first -- since obj contains spec -- but in the future we will probably make - // status its own object, and even if we don't, writes may be the result of a - // read-update-write loop, so the contents of spec may not actually be the spec that - // the CustomResource has *seen*. - newSpec, ok1 := newCustomResource["spec"] - oldSpec, ok2 := oldCustomResource["spec"] - - // spec is changed, created or deleted - if (ok1 && ok2 && !apiequality.Semantic.DeepEqual(oldSpec, newSpec)) || (ok1 && !ok2) || (!ok1 && ok2) { - oldAccessor, _ := meta.Accessor(oldCustomResourceObject) - newAccessor, _ := meta.Accessor(newCustomResourceObject) - newAccessor.SetGeneration(oldAccessor.GetGeneration() + 1) - } +func (customResourceDefinitionStorageStrategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object) { } -// Validate validates a new CustomResource. -func (a customResourceStrategy) Validate(ctx genericapirequest.Context, obj runtime.Object) field.ErrorList { - return a.validator.Validate(ctx, obj, a.scale) +func (a customResourceDefinitionStorageStrategy) Validate(ctx genericapirequest.Context, obj runtime.Object) field.ErrorList { + return a.validator.Validate(ctx, obj) } -// Canonicalize normalizes the object after validation. -func (customResourceStrategy) Canonicalize(obj runtime.Object) { -} - -// AllowCreateOnUpdate is false for CustomResources; this means a POST is -// needed to create one. -func (customResourceStrategy) AllowCreateOnUpdate() bool { +func (customResourceDefinitionStorageStrategy) AllowCreateOnUpdate() bool { return false } -// AllowUnconditionalUpdate is the default update policy for CustomResource objects. -func (customResourceStrategy) AllowUnconditionalUpdate() bool { +func (customResourceDefinitionStorageStrategy) AllowUnconditionalUpdate() bool { return false } -// ValidateUpdate is the default update validation for an end user updating status. -func (a customResourceStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList { - return a.validator.ValidateUpdate(ctx, obj, old, a.scale) +func (customResourceDefinitionStorageStrategy) Canonicalize(obj runtime.Object) { } -// GetAttrs returns labels and fields of a given object for filtering purposes. -func (a customResourceStrategy) GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) { +func (a customResourceDefinitionStorageStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList { + return a.validator.ValidateUpdate(ctx, obj, old) +} + +func (a customResourceDefinitionStorageStrategy) GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) { accessor, err := meta.Accessor(obj) if err != nil { return nil, nil, false, err @@ -172,13 +108,80 @@ func objectMetaFieldsSet(objectMeta metav1.Object, namespaceScoped bool) fields. } } -// MatchCustomResourceDefinitionStorage is the filter used by the generic etcd backend to route -// watch events from etcd to clients of the apiserver only interested in specific -// labels/fields. -func (a customResourceStrategy) MatchCustomResourceDefinitionStorage(label labels.Selector, field fields.Selector) apiserverstorage.SelectionPredicate { - return apiserverstorage.SelectionPredicate{ +func (a customResourceDefinitionStorageStrategy) MatchCustomResourceDefinitionStorage(label labels.Selector, field fields.Selector) storage.SelectionPredicate { + return storage.SelectionPredicate{ Label: label, Field: field, GetAttrs: a.GetAttrs, } } + +type customResourceValidator struct { + namespaceScoped bool + kind schema.GroupVersionKind + validator *validate.SchemaValidator +} + +func (a customResourceValidator) Validate(ctx genericapirequest.Context, obj runtime.Object) field.ErrorList { + accessor, err := meta.Accessor(obj) + if err != nil { + return field.ErrorList{field.Invalid(field.NewPath("metadata"), nil, err.Error())} + } + typeAccessor, err := meta.TypeAccessor(obj) + if err != nil { + return field.ErrorList{field.Invalid(field.NewPath("kind"), nil, err.Error())} + } + if typeAccessor.GetKind() != a.kind.Kind { + return field.ErrorList{field.Invalid(field.NewPath("kind"), typeAccessor.GetKind(), fmt.Sprintf("must be %v", a.kind.Kind))} + } + if typeAccessor.GetAPIVersion() != a.kind.Group+"/"+a.kind.Version { + return field.ErrorList{field.Invalid(field.NewPath("apiVersion"), typeAccessor.GetAPIVersion(), fmt.Sprintf("must be %v", a.kind.Group+"/"+a.kind.Version))} + } + + customResourceObject, ok := obj.(*unstructured.Unstructured) + // this will never happen. + if !ok { + return field.ErrorList{field.Invalid(field.NewPath(""), customResourceObject, fmt.Sprintf("has type %T. Must be a pointer to an Unstructured type", customResourceObject))} + } + + customResource := customResourceObject.UnstructuredContent() + if err = apiservervalidation.ValidateCustomResource(customResource, a.validator); err != nil { + return field.ErrorList{field.Invalid(field.NewPath(""), customResource, err.Error())} + } + + return validation.ValidateObjectMetaAccessor(accessor, a.namespaceScoped, validation.NameIsDNSSubdomain, field.NewPath("metadata")) +} + +func (a customResourceValidator) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList { + objAccessor, err := meta.Accessor(obj) + if err != nil { + return field.ErrorList{field.Invalid(field.NewPath("metadata"), nil, err.Error())} + } + oldAccessor, err := meta.Accessor(old) + if err != nil { + return field.ErrorList{field.Invalid(field.NewPath("metadata"), nil, err.Error())} + } + typeAccessor, err := meta.TypeAccessor(obj) + if err != nil { + return field.ErrorList{field.Invalid(field.NewPath("kind"), nil, err.Error())} + } + if typeAccessor.GetKind() != a.kind.Kind { + return field.ErrorList{field.Invalid(field.NewPath("kind"), typeAccessor.GetKind(), fmt.Sprintf("must be %v", a.kind.Kind))} + } + if typeAccessor.GetAPIVersion() != a.kind.Group+"/"+a.kind.Version { + return field.ErrorList{field.Invalid(field.NewPath("apiVersion"), typeAccessor.GetAPIVersion(), fmt.Sprintf("must be %v", a.kind.Group+"/"+a.kind.Version))} + } + + customResourceObject, ok := obj.(*unstructured.Unstructured) + // this will never happen. + if !ok { + return field.ErrorList{field.Invalid(field.NewPath(""), customResourceObject, fmt.Sprintf("has type %T. Must be a pointer to an Unstructured type", customResourceObject))} + } + + customResource := customResourceObject.UnstructuredContent() + if err = apiservervalidation.ValidateCustomResource(customResource, a.validator); err != nil { + return field.ErrorList{field.Invalid(field.NewPath(""), customResource, err.Error())} + } + + return validation.ValidateObjectMetaAccessorUpdate(objAccessor, oldAccessor, field.NewPath("metadata")) +} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor/BUILD b/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor/BUILD deleted file mode 100644 index e6150d203..000000000 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor/BUILD +++ /dev/null @@ -1,33 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["tableconvertor.go"], - importpath = "k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor", - visibility = ["//visibility:public"], - deps = [ - "//vendor/github.com/go-openapi/spec:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/meta/table:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library", - "//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library", - "//vendor/k8s.io/client-go/util/jsonpath:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [":package-srcs"], - tags = ["automanaged"], - visibility = ["//visibility:public"], -) diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor/tableconvertor.go b/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor/tableconvertor.go deleted file mode 100644 index 4eb62da6b..000000000 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor/tableconvertor.go +++ /dev/null @@ -1,120 +0,0 @@ -/* -Copyright 2018 The Kubernetes 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 tableconvertor - -import ( - "bytes" - "fmt" - "strings" - - "github.com/go-openapi/spec" - - "k8s.io/apimachinery/pkg/api/meta" - metatable "k8s.io/apimachinery/pkg/api/meta/table" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" - "k8s.io/apimachinery/pkg/runtime" - genericapirequest "k8s.io/apiserver/pkg/endpoints/request" - "k8s.io/apiserver/pkg/registry/rest" - "k8s.io/client-go/util/jsonpath" -) - -const printColumnsKey = "x-kubernetes-print-columns" - -var swaggerMetadataDescriptions = metav1.ObjectMeta{}.SwaggerDoc() - -// New creates a new table convertor for the provided OpenAPI schema. If the printer definition cannot be parsed, -// error will be returned along with a default table convertor. -func New(extensions spec.Extensions) (rest.TableConvertor, error) { - headers := []metav1beta1.TableColumnDefinition{ - {Name: "Name", Type: "string", Format: "name", Description: swaggerMetadataDescriptions["name"]}, - {Name: "Created At", Type: "date", Description: swaggerMetadataDescriptions["creationTimestamp"]}, - } - c := &convertor{ - headers: headers, - } - format, ok := extensions.GetString(printColumnsKey) - if !ok { - return c, nil - } - // "x-kubernetes-print-columns": "custom-columns=NAME:.metadata.name,RSRC:.metadata.resourceVersion" - parts := strings.SplitN(format, "=", 2) - if len(parts) != 2 || parts[0] != "custom-columns" { - return c, fmt.Errorf("unrecognized column definition in 'x-kubernetes-print-columns', only support 'custom-columns=NAME=JSONPATH[,NAME=JSONPATH]'") - } - columnSpecs := strings.Split(parts[1], ",") - var columns []*jsonpath.JSONPath - for _, spec := range columnSpecs { - parts := strings.SplitN(spec, ":", 2) - if len(parts) != 2 || len(parts[0]) == 0 || len(parts[1]) == 0 { - return c, fmt.Errorf("unrecognized column definition in 'x-kubernetes-print-columns', must specify NAME=JSONPATH: %s", spec) - } - path := jsonpath.New(parts[0]) - if err := path.Parse(parts[1]); err != nil { - return c, fmt.Errorf("unrecognized column definition in 'x-kubernetes-print-columns': %v", spec) - } - path.AllowMissingKeys(true) - columns = append(columns, path) - headers = append(headers, metav1beta1.TableColumnDefinition{ - Name: parts[0], - Type: "string", - Description: fmt.Sprintf("Custom resource definition column from OpenAPI (in JSONPath format): %s", parts[1]), - }) - } - c.columns = columns - c.headers = headers - return c, nil -} - -type convertor struct { - headers []metav1beta1.TableColumnDefinition - columns []*jsonpath.JSONPath -} - -func (c *convertor) ConvertToTable(ctx genericapirequest.Context, obj runtime.Object, tableOptions runtime.Object) (*metav1beta1.Table, error) { - table := &metav1beta1.Table{ - ColumnDefinitions: c.headers, - } - if m, err := meta.ListAccessor(obj); err == nil { - table.ResourceVersion = m.GetResourceVersion() - table.SelfLink = m.GetSelfLink() - table.Continue = m.GetContinue() - } else { - if m, err := meta.CommonAccessor(obj); err == nil { - table.ResourceVersion = m.GetResourceVersion() - table.SelfLink = m.GetSelfLink() - } - } - - var err error - buf := &bytes.Buffer{} - table.Rows, err = metatable.MetaToTableRow(obj, func(obj runtime.Object, m metav1.Object, name, age string) ([]interface{}, error) { - cells := make([]interface{}, 2, 2+len(c.columns)) - cells[0] = name - cells[1] = age - for _, column := range c.columns { - if err := column.Execute(buf, obj); err != nil { - cells = append(cells, nil) - continue - } - cells = append(cells, buf.String()) - buf.Reset() - } - return cells, nil - }) - return table, err -} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/validator.go b/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/validator.go deleted file mode 100644 index ef5023dc6..000000000 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresource/validator.go +++ /dev/null @@ -1,241 +0,0 @@ -/* -Copyright 2018 The Kubernetes 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 customresource - -import ( - "fmt" - "math" - "strings" - - "github.com/go-openapi/validate" - - "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/api/validation" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/validation/field" - genericapirequest "k8s.io/apiserver/pkg/endpoints/request" - - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" - apiservervalidation "k8s.io/apiextensions-apiserver/pkg/apiserver/validation" -) - -type customResourceValidator struct { - namespaceScoped bool - kind schema.GroupVersionKind - schemaValidator *validate.SchemaValidator - statusSchemaValidator *validate.SchemaValidator -} - -func (a customResourceValidator) Validate(ctx genericapirequest.Context, obj runtime.Object, scale *apiextensions.CustomResourceSubresourceScale) field.ErrorList { - accessor, err := meta.Accessor(obj) - if err != nil { - return field.ErrorList{field.Invalid(field.NewPath("metadata"), nil, err.Error())} - } - typeAccessor, err := meta.TypeAccessor(obj) - if err != nil { - return field.ErrorList{field.Invalid(field.NewPath("kind"), nil, err.Error())} - } - if typeAccessor.GetKind() != a.kind.Kind { - return field.ErrorList{field.Invalid(field.NewPath("kind"), typeAccessor.GetKind(), fmt.Sprintf("must be %v", a.kind.Kind))} - } - if typeAccessor.GetAPIVersion() != a.kind.Group+"/"+a.kind.Version { - return field.ErrorList{field.Invalid(field.NewPath("apiVersion"), typeAccessor.GetAPIVersion(), fmt.Sprintf("must be %v", a.kind.Group+"/"+a.kind.Version))} - } - - customResourceObject, ok := obj.(*unstructured.Unstructured) - // this will never happen. - if !ok { - return field.ErrorList{field.Invalid(field.NewPath(""), customResourceObject, fmt.Sprintf("has type %T. Must be a pointer to an Unstructured type", customResourceObject))} - } - customResource := customResourceObject.UnstructuredContent() - - if err = apiservervalidation.ValidateCustomResource(customResource, a.schemaValidator); err != nil { - return field.ErrorList{field.Invalid(field.NewPath(""), customResource, err.Error())} - } - - if scale != nil { - // validate specReplicas - specReplicasPath := strings.TrimPrefix(scale.SpecReplicasPath, ".") // ignore leading period - specReplicas, _, err := unstructured.NestedInt64(customResource, strings.Split(specReplicasPath, ".")...) - if err != nil { - return field.ErrorList{field.Invalid(field.NewPath(scale.SpecReplicasPath), specReplicas, err.Error())} - } - if specReplicas < 0 { - return field.ErrorList{field.Invalid(field.NewPath(scale.SpecReplicasPath), specReplicas, "should be a non-negative integer")} - } - if specReplicas > math.MaxInt32 { - return field.ErrorList{field.Invalid(field.NewPath(scale.SpecReplicasPath), specReplicas, fmt.Sprintf("should be less than or equal to %v", math.MaxInt32))} - } - - // validate statusReplicas - statusReplicasPath := strings.TrimPrefix(scale.StatusReplicasPath, ".") // ignore leading period - statusReplicas, _, err := unstructured.NestedInt64(customResource, strings.Split(statusReplicasPath, ".")...) - if err != nil { - return field.ErrorList{field.Invalid(field.NewPath(scale.StatusReplicasPath), statusReplicas, err.Error())} - } - if statusReplicas < 0 { - return field.ErrorList{field.Invalid(field.NewPath(scale.StatusReplicasPath), statusReplicas, "should be a non-negative integer")} - } - if statusReplicas > math.MaxInt32 { - return field.ErrorList{field.Invalid(field.NewPath(scale.StatusReplicasPath), statusReplicas, fmt.Sprintf("should be less than or equal to %v", math.MaxInt32))} - } - - // validate labelSelector - if scale.LabelSelectorPath != nil { - labelSelectorPath := strings.TrimPrefix(*scale.LabelSelectorPath, ".") // ignore leading period - labelSelector, _, err := unstructured.NestedString(customResource, strings.Split(labelSelectorPath, ".")...) - if err != nil { - return field.ErrorList{field.Invalid(field.NewPath(*scale.LabelSelectorPath), labelSelector, err.Error())} - } - } - } - - return validation.ValidateObjectMetaAccessor(accessor, a.namespaceScoped, validation.NameIsDNSSubdomain, field.NewPath("metadata")) -} - -func (a customResourceValidator) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object, scale *apiextensions.CustomResourceSubresourceScale) field.ErrorList { - objAccessor, err := meta.Accessor(obj) - if err != nil { - return field.ErrorList{field.Invalid(field.NewPath("metadata"), nil, err.Error())} - } - oldAccessor, err := meta.Accessor(old) - if err != nil { - return field.ErrorList{field.Invalid(field.NewPath("metadata"), nil, err.Error())} - } - typeAccessor, err := meta.TypeAccessor(obj) - if err != nil { - return field.ErrorList{field.Invalid(field.NewPath("kind"), nil, err.Error())} - } - if typeAccessor.GetKind() != a.kind.Kind { - return field.ErrorList{field.Invalid(field.NewPath("kind"), typeAccessor.GetKind(), fmt.Sprintf("must be %v", a.kind.Kind))} - } - if typeAccessor.GetAPIVersion() != a.kind.Group+"/"+a.kind.Version { - return field.ErrorList{field.Invalid(field.NewPath("apiVersion"), typeAccessor.GetAPIVersion(), fmt.Sprintf("must be %v", a.kind.Group+"/"+a.kind.Version))} - } - - customResourceObject, ok := obj.(*unstructured.Unstructured) - // this will never happen. - if !ok { - return field.ErrorList{field.Invalid(field.NewPath(""), customResourceObject, fmt.Sprintf("has type %T. Must be a pointer to an Unstructured type", customResourceObject))} - } - customResource := customResourceObject.UnstructuredContent() - - if err = apiservervalidation.ValidateCustomResource(customResource, a.schemaValidator); err != nil { - return field.ErrorList{field.Invalid(field.NewPath(""), customResource, err.Error())} - } - - if scale != nil { - // validate specReplicas - specReplicasPath := strings.TrimPrefix(scale.SpecReplicasPath, ".") // ignore leading period - specReplicas, _, err := unstructured.NestedInt64(customResource, strings.Split(specReplicasPath, ".")...) - if err != nil { - return field.ErrorList{field.Invalid(field.NewPath(scale.SpecReplicasPath), specReplicas, err.Error())} - } - if specReplicas < 0 { - return field.ErrorList{field.Invalid(field.NewPath(scale.SpecReplicasPath), specReplicas, "should be a non-negative integer")} - } - if specReplicas > math.MaxInt32 { - return field.ErrorList{field.Invalid(field.NewPath(scale.SpecReplicasPath), specReplicas, fmt.Sprintf("should be less than or equal to %v", math.MaxInt32))} - } - - // validate statusReplicas - statusReplicasPath := strings.TrimPrefix(scale.StatusReplicasPath, ".") // ignore leading period - statusReplicas, _, err := unstructured.NestedInt64(customResource, strings.Split(statusReplicasPath, ".")...) - if err != nil { - return field.ErrorList{field.Invalid(field.NewPath(scale.StatusReplicasPath), statusReplicas, err.Error())} - } - if statusReplicas < 0 { - return field.ErrorList{field.Invalid(field.NewPath(scale.StatusReplicasPath), statusReplicas, "should be a non-negative integer")} - } - if statusReplicas > math.MaxInt32 { - return field.ErrorList{field.Invalid(field.NewPath(scale.StatusReplicasPath), statusReplicas, fmt.Sprintf("should be less than or equal to %v", math.MaxInt32))} - } - - // validate labelSelector - if scale.LabelSelectorPath != nil { - labelSelectorPath := strings.TrimPrefix(*scale.LabelSelectorPath, ".") // ignore leading period - labelSelector, _, err := unstructured.NestedString(customResource, strings.Split(labelSelectorPath, ".")...) - if err != nil { - return field.ErrorList{field.Invalid(field.NewPath(*scale.LabelSelectorPath), labelSelector, err.Error())} - } - } - } - - return validation.ValidateObjectMetaAccessorUpdate(objAccessor, oldAccessor, field.NewPath("metadata")) -} - -func (a customResourceValidator) ValidateStatusUpdate(ctx genericapirequest.Context, obj, old runtime.Object, scale *apiextensions.CustomResourceSubresourceScale) field.ErrorList { - objAccessor, err := meta.Accessor(obj) - if err != nil { - return field.ErrorList{field.Invalid(field.NewPath("metadata"), nil, err.Error())} - } - oldAccessor, err := meta.Accessor(old) - if err != nil { - return field.ErrorList{field.Invalid(field.NewPath("metadata"), nil, err.Error())} - } - typeAccessor, err := meta.TypeAccessor(obj) - if err != nil { - return field.ErrorList{field.Invalid(field.NewPath("kind"), nil, err.Error())} - } - if typeAccessor.GetKind() != a.kind.Kind { - return field.ErrorList{field.Invalid(field.NewPath("kind"), typeAccessor.GetKind(), fmt.Sprintf("must be %v", a.kind.Kind))} - } - if typeAccessor.GetAPIVersion() != a.kind.Group+"/"+a.kind.Version { - return field.ErrorList{field.Invalid(field.NewPath("apiVersion"), typeAccessor.GetAPIVersion(), fmt.Sprintf("must be %v", a.kind.Group+"/"+a.kind.Version))} - } - - customResourceObject, ok := obj.(*unstructured.Unstructured) - // this will never happen. - if !ok { - return field.ErrorList{field.Invalid(field.NewPath(""), customResourceObject, fmt.Sprintf("has type %T. Must be a pointer to an Unstructured type", customResourceObject))} - } - customResource := customResourceObject.UnstructuredContent() - - // validate only the status - customResourceStatus := customResource["status"] - if err = apiservervalidation.ValidateCustomResource(customResourceStatus, a.statusSchemaValidator); err != nil { - return field.ErrorList{field.Invalid(field.NewPath("status"), customResourceStatus, err.Error())} - } - - if scale != nil { - // validate statusReplicas - statusReplicasPath := strings.TrimPrefix(scale.StatusReplicasPath, ".") // ignore leading period - statusReplicas, _, err := unstructured.NestedInt64(customResource, strings.Split(statusReplicasPath, ".")...) - if err != nil { - return field.ErrorList{field.Invalid(field.NewPath(scale.StatusReplicasPath), statusReplicas, err.Error())} - } - if statusReplicas < 0 { - return field.ErrorList{field.Invalid(field.NewPath(scale.StatusReplicasPath), statusReplicas, "should be a non-negative integer")} - } - if statusReplicas > math.MaxInt32 { - return field.ErrorList{field.Invalid(field.NewPath(scale.StatusReplicasPath), statusReplicas, fmt.Sprintf("should be less than or equal to %v", math.MaxInt32))} - } - - // validate labelSelector - if scale.LabelSelectorPath != nil { - labelSelectorPath := strings.TrimPrefix(*scale.LabelSelectorPath, ".") // ignore leading period - labelSelector, _, err := unstructured.NestedString(customResource, strings.Split(labelSelectorPath, ".")...) - if err != nil { - return field.ErrorList{field.Invalid(field.NewPath(*scale.LabelSelectorPath), labelSelector, err.Error())} - } - } - } - - return validation.ValidateObjectMetaAccessorUpdate(objAccessor, oldAccessor, field.NewPath("metadata")) -} diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/etcd.go b/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/etcd.go index c501c6a08..85d981f1a 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/etcd.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/etcd.go @@ -62,7 +62,7 @@ var _ rest.ShortNamesProvider = &REST{} // ShortNames implements the ShortNamesProvider interface. Returns a list of short names for a resource. func (r *REST) ShortNames() []string { - return []string{"crd", "crds"} + return []string{"crd"} } // Delete adds the CRD finalizer to the list diff --git a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy.go b/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy.go index 7e44fa4c2..849cd6f8e 100644 --- a/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy.go +++ b/vendor/k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition/strategy.go @@ -35,7 +35,6 @@ import ( apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features" ) -// strategy implements behavior for CustomResources. type strategy struct { runtime.ObjectTyper names.NameGenerator @@ -49,7 +48,6 @@ func (strategy) NamespaceScoped() bool { return false } -// PrepareForCreate clears the status of a CustomResourceDefinition before creation. func (strategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Object) { crd := obj.(*apiextensions.CustomResourceDefinition) crd.Status = apiextensions.CustomResourceDefinitionStatus{} @@ -59,12 +57,8 @@ func (strategy) PrepareForCreate(ctx genericapirequest.Context, obj runtime.Obje if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceValidation) { crd.Spec.Validation = nil } - if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) { - crd.Spec.Subresources = nil - } } -// PrepareForUpdate clears fields that are not allowed to be set by end users on update. func (strategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime.Object) { newCRD := obj.(*apiextensions.CustomResourceDefinition) oldCRD := old.(*apiextensions.CustomResourceDefinition) @@ -86,33 +80,23 @@ func (strategy) PrepareForUpdate(ctx genericapirequest.Context, obj, old runtime newCRD.Spec.Validation = nil oldCRD.Spec.Validation = nil } - if !utilfeature.DefaultFeatureGate.Enabled(apiextensionsfeatures.CustomResourceSubresources) { - newCRD.Spec.Subresources = nil - oldCRD.Spec.Subresources = nil - } } -// Validate validates a new CustomResourceDefinition. func (strategy) Validate(ctx genericapirequest.Context, obj runtime.Object) field.ErrorList { return validation.ValidateCustomResourceDefinition(obj.(*apiextensions.CustomResourceDefinition)) } -// AllowCreateOnUpdate is false for CustomResourceDefinition; this means a POST is -// needed to create one. func (strategy) AllowCreateOnUpdate() bool { return false } -// AllowUnconditionalUpdate is the default update policy for CustomResourceDefinition objects. func (strategy) AllowUnconditionalUpdate() bool { return false } -// Canonicalize normalizes the object after validation. func (strategy) Canonicalize(obj runtime.Object) { } -// ValidateUpdate is the default update validation for an end user updating status. func (strategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.Object) field.ErrorList { return validation.ValidateCustomResourceDefinitionUpdate(obj.(*apiextensions.CustomResourceDefinition), old.(*apiextensions.CustomResourceDefinition)) } @@ -159,11 +143,10 @@ func (statusStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old run return validation.ValidateUpdateCustomResourceDefinitionStatus(obj.(*apiextensions.CustomResourceDefinition), old.(*apiextensions.CustomResourceDefinition)) } -// GetAttrs returns labels and fields of a given object for filtering purposes. func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) { apiserver, ok := obj.(*apiextensions.CustomResourceDefinition) if !ok { - return nil, nil, false, fmt.Errorf("given object is not a CustomResourceDefinition") + return nil, nil, false, fmt.Errorf("given object is not a CustomResourceDefinition.") } return labels.Set(apiserver.ObjectMeta.Labels), CustomResourceDefinitionToSelectableFields(apiserver), apiserver.Initializers != nil, nil } diff --git a/vendor/k8s.io/apiextensions-apiserver/test/integration/BUILD b/vendor/k8s.io/apiextensions-apiserver/test/integration/BUILD index b9617e41a..1aca59abf 100644 --- a/vendor/k8s.io/apiextensions-apiserver/test/integration/BUILD +++ b/vendor/k8s.io/apiextensions-apiserver/test/integration/BUILD @@ -11,32 +11,24 @@ go_test( "basic_test.go", "finalization_test.go", "registration_test.go", - "subresources_test.go", "validation_test.go", - "yaml_test.go", ], + importpath = "k8s.io/apiextensions-apiserver/test/integration", tags = ["integration"], deps = [ "//vendor/github.com/coreos/etcd/clientv3:go_default_library", - "//vendor/github.com/ghodss/yaml:go_default_library", "//vendor/github.com/stretchr/testify/require:go_default_library", - "//vendor/k8s.io/api/autoscaling/v1:go_default_library", "//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library", "//vendor/k8s.io/apiextensions-apiserver/pkg/apiserver:go_default_library", - "//vendor/k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset:go_default_library", - "//vendor/k8s.io/apiextensions-apiserver/pkg/features:go_default_library", "//vendor/k8s.io/apiextensions-apiserver/test/integration/testserver:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/types:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//vendor/k8s.io/apimachinery/pkg/watch:go_default_library", - "//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library", - "//vendor/k8s.io/apiserver/pkg/util/feature/testing:go_default_library", "//vendor/k8s.io/client-go/dynamic:go_default_library", ], ) diff --git a/vendor/k8s.io/apiextensions-apiserver/test/integration/apiserver.local.config/certificates/apiserver.crt b/vendor/k8s.io/apiextensions-apiserver/test/integration/apiserver.local.config/certificates/apiserver.crt index 0b52619bf..6bd8196e8 100644 --- a/vendor/k8s.io/apiextensions-apiserver/test/integration/apiserver.local.config/certificates/apiserver.crt +++ b/vendor/k8s.io/apiextensions-apiserver/test/integration/apiserver.local.config/certificates/apiserver.crt @@ -1,19 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDFTCCAf2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRsb2Nh -bGhvc3RAMTUxNTQ2MjIwNjAgFw0xODAxMDkwMTQzMjZaGA8yMTE4MDEwOTAxNDMy -NlowHzEdMBsGA1UEAwwUbG9jYWxob3N0QDE1MTU0NjIyMDYwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQC2hIORzonehlNadYyI30v1Jj8lhhABuiWiTSkl -KCLqZjwBfWfSC4w02zxi2SAH9ju20XCJrUauwPq1qXCp/CqXC/rVgZrzluDlpJpe -gF9AilQvGOxhrZhV4kqpOjGVE78uOmpfxiOyNermoJ0OVE8ugh3s/LLTNK/qmCAX -uEYTQccAvNEiPX3XPBCiaFlSCkUNS0zp12mJNP43+KF9y0CbtYs1gXKHmmJVSpjR -YmcuJJUfHxNrV2YR3ek6O4IIJFIlnLxgpjRBseBPkTenAT3S2YY9MyQkkBrRSPBa -vLM24al3KDvXYikYe3WpxeYNHGNcHIgR+hKlRTQ5VrWlfx9dAgMBAAGjWjBYMA4G -A1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTAD -AQH/MCAGA1UdEQQZMBeCCWxvY2FsaG9zdIcEfwAAAYcEfwAAATANBgkqhkiG9w0B -AQsFAAOCAQEAFhW8cVTraHPNsE+Jo0ZvcE2ic8lEzeOhWI2O/fpkrUJS5LptPKHS -nTK+CPxA0zhIS/vlJznIabeddXwtq7Xb5SwlJMHYMnHD6f5qwpD22D2dxJJa5sma -3yrK/4CutuEae08qqSeakfgCjcHLL9p7FZWxujkV9/5CEH5lFWYLGumyIoS46Svf -nSfDFKTrOj8P60ncCoWcSpMbdVQBDuKlIZuBMmz9CguC1CtuQWPDUmOGJuPs/+So -yusHbBfj+ATUWDYTg1lLjOIOSJpHGUQkvS+8Bo47SThD/b4w2i6VC72ldxtBuxGf -L7+jALMhMhiQD+Q4qsNuyvvNQLoYcTTFTw== +MIIDEzCCAfugAwIBAgIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRsb2Nh +bGhvc3RAMTQ5MzY2NDQ4OTAeFw0xNzA1MDExODQ4MDlaFw0xODA1MDExODQ4MDla +MB8xHTAbBgNVBAMMFGxvY2FsaG9zdEAxNDkzNjY0NDg5MIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAy6tMZcDbG1J4vbX+YdiPswxqO+hX1r+i9+DFb1N/ +xyodBbprn1Mmd2k1lv3AkiZKm38v7dgzQ9/teA8Jm/1tyjjZSV/CxsZZWNuukPGU +ykEtn4mvkb5tOI1159ieTBiL4mKx5VNq8DkIpy9CT22Ud9dHkJaxJHcIF601hXHg +GIRla/6CRlkY/GFUItl1oij4sgzXRTS2pdv8lsmt2s7dXj737l10QCz9YDVuGSfu +rYoHGwY5ofYYFWzscD7Ds4O0tPdu4mSPIu753K7nB3ilfBi+tUWcSXpw9wE4+hIF +a1In8jnM+lw5/j/UoghrCtQ54BGWzpivPPXKv2dlNIOPiwIDAQABo1owWDAOBgNV +HQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB +/zAgBgNVHREEGTAXgglsb2NhbGhvc3SHBH8AAAGHBH8AAAEwDQYJKoZIhvcNAQEL +BQADggEBAJbxTi/0Joxx/oja4QDksbWroip0qVJKh1ic7ryai52aSBTcHMF9pWiL +047lL3sL0sN0YavXPUiow4PMTQm14W01ciwuZj5DCCaXnmnGtBy0fy8ifUdQoD/J +9pvLQMWAsx+GP2XzY+KxYFQairKS7BehEF/d24TgNHPskgc2p2XgK3Z7Ipp7hQrj +yZiTNromeULT12d5Zuwf+IeDp3aopGyhxCTOoc+RCz4MKLfKov40xjlaA4jVWazd +ccHWnagwM5lDlXnmCqZRVvyOWaUulJCEzRFfRTHFxKgj6DSPNt00wHXNmQUvjhN/ +YXFAkfKQQEs3qQRXoHAXKquplnLgjyA= -----END CERTIFICATE----- diff --git a/vendor/k8s.io/apiextensions-apiserver/test/integration/apiserver.local.config/certificates/apiserver.key b/vendor/k8s.io/apiextensions-apiserver/test/integration/apiserver.local.config/certificates/apiserver.key index d4878784e..152fc1b6f 100644 --- a/vendor/k8s.io/apiextensions-apiserver/test/integration/apiserver.local.config/certificates/apiserver.key +++ b/vendor/k8s.io/apiextensions-apiserver/test/integration/apiserver.local.config/certificates/apiserver.key @@ -1,27 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAtoSDkc6J3oZTWnWMiN9L9SY/JYYQAbolok0pJSgi6mY8AX1n -0guMNNs8YtkgB/Y7ttFwia1GrsD6talwqfwqlwv61YGa85bg5aSaXoBfQIpULxjs -Ya2YVeJKqToxlRO/LjpqX8YjsjXq5qCdDlRPLoId7Pyy0zSv6pggF7hGE0HHALzR -Ij191zwQomhZUgpFDUtM6ddpiTT+N/ihfctAm7WLNYFyh5piVUqY0WJnLiSVHx8T -a1dmEd3pOjuCCCRSJZy8YKY0QbHgT5E3pwE90tmGPTMkJJAa0UjwWryzNuGpdyg7 -12IpGHt1qcXmDRxjXByIEfoSpUU0OVa1pX8fXQIDAQABAoIBAERy2ezaqnXbpnLs -VrIWHCRqHZBzAJnFN8vwaBfZP47snGBqqX7qecBw3+qqRwr1W1uqnCvl4fYzxVJP -o0L8oPRYt89OddAYq2s0GfiK6C4KMpwfGrdfJRxAa4OfoWypJS+vFKmqY0S4V8n6 -Pixbjf6BKbvw4Re4UKkIODDtGMqrZFVKcFe8LCnd3D+7jvt0M/WjEhrepWxscJh3 -aHgDzsLzCv1DNjgZfoRZubkK3bdndMaL6NhaKNBz6S7CT9XmZsJaWkmBXs9zOoyr -0hKP0A11cm6a7LsmxX5h4uaQLh66KHUPbV4KjKgKiGkSS9cnZoXHFZLOplOfozje -1DKitAECgYEA2eWiRNByNIqqRPvBtD8ydavOLk6iLlLt+LkCpGupgELs53WS5fTT -TxbyVq+897qeW2Klir7jZFWG3Q+EaBATxMYON+jb7QnIz8gX9lh1PpUlo88BiQzO -hAIx2uV19KM0ftXYVTSAUh1N2cgoOWGUWLaeMPdxPOlJwvM25hSfp90CgYEA1m8W -vWBO8X5LXM9g+fO1TFSlTnUJW1gWrnOw4VmU2+DbqNmtefpVrqDa5Iw2+mU+EBgA -d3wdAHARXpc2MGcIRnRbHn+gXJVHA+gA7H9LSZ4Yi0qJZbNVAgRySs2iBYUcunsR -AXkS7sPGQinfnjKh6vhYVErh5jA+cvS8CXZtnYECgYBmh61hYAw9OPqB100AebRO -tncgRxP9ZDxiCvx5TcfGeLds+mATIK7FynBh5fOvRfr52WM39DafobcCEiklplsG -/oL2P/YshaweSXMtEdapihjaCbAZQxNx/m5jKBHm+VzcSdev0DKJcQyO66Yxyf65 -98RcGjMIjGWO/E7a2N1/aQKBgCPrY+HBGjg1saYQTuxPuJTasP4deL3GWbZLRtvY -x6i1V9ZG8Fo4ZtXjuAcEvcjf4K+NdbaOIcWLAD3aEoe1GpvCrejD9DbOAqFS4aS8 -Bf6E7xOWHsHccmbuG78QBw3pqFBMgSLABz3bqYA3x2+Wh6z2gMVN7d1DQ5K6EC19 -mwsBAoGBAKZBgqRHRq1Ch3SWb5Q+SgUvNyQ+PAIwCve0vA4mMIK6EGqU/8wbU01B -5/UkCfT+ovDeDuyeaZbTWzwUC4Mrg4C9rThrK5WLc43Dig6G1HhfjdLA+gdKFOjh -FpocOI2FEwbmj5Mka6n3TSFI8c55ubYdyXQu92DoFt4dTOJStUn2 +MIIEpQIBAAKCAQEAy6tMZcDbG1J4vbX+YdiPswxqO+hX1r+i9+DFb1N/xyodBbpr +n1Mmd2k1lv3AkiZKm38v7dgzQ9/teA8Jm/1tyjjZSV/CxsZZWNuukPGUykEtn4mv +kb5tOI1159ieTBiL4mKx5VNq8DkIpy9CT22Ud9dHkJaxJHcIF601hXHgGIRla/6C +RlkY/GFUItl1oij4sgzXRTS2pdv8lsmt2s7dXj737l10QCz9YDVuGSfurYoHGwY5 +ofYYFWzscD7Ds4O0tPdu4mSPIu753K7nB3ilfBi+tUWcSXpw9wE4+hIFa1In8jnM ++lw5/j/UoghrCtQ54BGWzpivPPXKv2dlNIOPiwIDAQABAoIBABy4qWtoCP4PYUuP +kLIHsiwTwh90on58Q+Uk43LRmaFihPk70tWDCleolJAYdMGneLn4869c383glEJs +DHTdBlCQN8QrJvKVIiBvymxSRSNIkcB/0CyDaC+jc08gsyIUDBX+yQuH+fqqcFfz +SCyfTWKhD0yKk6yKxK9iE7wf1PRf5uLtJD6x1vV0NBmsHH++feODjNVsHDRvnwy6 +3KXkgSvfCTQ7qnQPZ/MSsRxWRdMBCnhaQq9qRnJ8bv8XotrCsEG5laMybriyJYXX +wvr9Dt04ciUD/g3qwIPy1ygMAKE9ya8hivSRURptZxz9SKCenWWihsfIzk4uyOi+ +sVDkJVECgYEA2981ZhbkruG5JhOsWVXTxDlXOrjI0pUqfej0WEp8lwdBMOrTXFs1 +cB8kdSocVC5GnMTbg6bqJrfglbNDOA7sUA8E8APLFFUAAvPwVfnrdDWk+0jK7atu +2sixQGeIB97Y6ojWfSbjyA/0p3Z0zCTfP5SR6xt4hVWhInB11m5IpO0CgYEA7SKH +bfWPZ0xfkFdM2X2cWQjt4zYHIUQqAKLPs2OjPTBC8PioNiZlvZq9bNseYR+eyIg6 +P9Kwe4KV/hzOSScf7JYpsN+YQ1+4Y+E63BkhAHXyz7y/vD+DA/Z83oKbelQtJqwq +W+Zo1OGJrfZwEKK5JWN9HF+KI9Z1iMyZoyw8L1cCgYEAtaLDfj7TVBVs2qPN8U8R +zjyAbyZP4IcRv0o+8OE345w+oqabTOScVK+lcpUDKhfAhamqniu5q5qjkYextBG/ +7rM5pP29OmKty8KxfJUlia73SA9udMD2pw68PzRIEBhsofPBHUqPSarEtcMJ4ctk +EiYuFUdwXNXMc6Lr9eTNZlECgYEAsfFJIvAzjdY3l76KwmGJox4aNHdkXkgiJJwH +s5s+8Tl34g8VWpzxl5e4MSkz4LmzktL2stHM8MGLAEZpXWdog0YjPsBqJ5R6byih +3GtW4lufutbuIbqe+6hJB0eGmAL2ZqCmoJODcstTXyEf8rvIpw/C4DmpFT9mryKo +31LgTr0CgYEAuxusmnR2vzZP/RjpjzmZcvIHf4xORG+SXlg3BXsSEd6+g3Rqiy5t +Q0UkHHwYnYurBmJ2HL1LG9mZwU89D00F/4mJpJuWfwqtqvodIRZ7bimyGGbvKZ1t +BGLmUssF5MYn75v7E5opxcc51aieW8nUQbop/PPMvWsYLrL/mcJNBpA= -----END RSA PRIVATE KEY----- diff --git a/vendor/k8s.io/apiextensions-apiserver/test/integration/basic_test.go b/vendor/k8s.io/apiextensions-apiserver/test/integration/basic_test.go index e373a178a..72fdf592a 100644 --- a/vendor/k8s.io/apiextensions-apiserver/test/integration/basic_test.go +++ b/vendor/k8s.io/apiextensions-apiserver/test/integration/basic_test.go @@ -35,7 +35,7 @@ import ( ) func TestServerUp(t *testing.T) { - stopCh, _, _, err := testserver.StartDefaultServerWithClients() + stopCh, _, _, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -43,7 +43,7 @@ func TestServerUp(t *testing.T) { } func TestNamespaceScopedCRUD(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -61,7 +61,7 @@ func TestNamespaceScopedCRUD(t *testing.T) { } func TestClusterScopedCRUD(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -347,7 +347,7 @@ func TestDiscovery(t *testing.T) { group := "mygroup.example.com" version := "v1beta1" - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -388,14 +388,10 @@ func TestDiscovery(t *testing.T) { if !reflect.DeepEqual([]string(r.Verbs), expectedVerbs) { t.Fatalf("Unexpected verbs for resource \"noxus\" in group version %v/%v via discovery: expected=%v got=%v", group, version, expectedVerbs, r.Verbs) } - - if !reflect.DeepEqual(r.Categories, []string{"all"}) { - t.Fatalf("Expected exactly the category \"all\" in group version %v/%v via discovery, got: %v", group, version, r.Categories) - } } func TestNoNamespaceReject(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -434,7 +430,7 @@ func TestNoNamespaceReject(t *testing.T) { } func TestSameNameDiffNamespace(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -454,7 +450,7 @@ func TestSameNameDiffNamespace(t *testing.T) { } func TestSelfLink(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -501,13 +497,13 @@ func TestSelfLink(t *testing.T) { t.Fatal(err) } - if e, a := "/apis/mygroup.example.com/v1beta1/curlets/foo", createdCurletInstance.GetSelfLink(); e != a { + if e, a := "/apis/mygroup.example.com/v1beta1/foo", createdCurletInstance.GetSelfLink(); e != a { t.Errorf("expected %v, got %v", e, a) } } func TestPreserveInt(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -552,7 +548,7 @@ func TestPreserveInt(t *testing.T) { } func TestPatch(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -582,17 +578,6 @@ func TestPatch(t *testing.T) { t.Fatalf("unexpected error: %v", err) } - // this call waits for the resourceVersion to be reached in the cache before returning. - // We need to do this because the patch gets its initial object from the storage, and the cache serves that. - // If it is out of date, then our initial patch is applied to an old resource version, which conflicts - // and then the updated object shows a conflicting diff, which permanently fails the patch. - // This gives expected stability in the patch without retrying on an known number of conflicts below in the test. - // See https://issue.k8s.io/42644 - _, err = noxuNamespacedResourceClient.Get("foo", metav1.GetOptions{ResourceVersion: createdNoxuInstance.GetResourceVersion()}) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - // a patch with no change createdNoxuInstance, err = noxuNamespacedResourceClient.Patch("foo", types.MergePatchType, patch) if err != nil { @@ -626,7 +611,7 @@ func TestPatch(t *testing.T) { } func TestCrossNamespaceListWatch(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -762,7 +747,7 @@ func checkNamespacesWatchHelper(t *testing.T, ns string, namespacedwatch watch.I } func TestNameConflict(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } diff --git a/vendor/k8s.io/apiextensions-apiserver/test/integration/finalization_test.go b/vendor/k8s.io/apiextensions-apiserver/test/integration/finalization_test.go index 57b04884b..126348704 100644 --- a/vendor/k8s.io/apiextensions-apiserver/test/integration/finalization_test.go +++ b/vendor/k8s.io/apiextensions-apiserver/test/integration/finalization_test.go @@ -28,7 +28,7 @@ import ( ) func TestFinalization(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() require.NoError(t, err) defer close(stopCh) diff --git a/vendor/k8s.io/apiextensions-apiserver/test/integration/registration_test.go b/vendor/k8s.io/apiextensions-apiserver/test/integration/registration_test.go index 7cdd2bc7c..a72ce2dcf 100644 --- a/vendor/k8s.io/apiextensions-apiserver/test/integration/registration_test.go +++ b/vendor/k8s.io/apiextensions-apiserver/test/integration/registration_test.go @@ -30,7 +30,6 @@ import ( apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" extensionsapiserver "k8s.io/apiextensions-apiserver/pkg/apiserver" - apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" "k8s.io/apiextensions-apiserver/test/integration/testserver" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" @@ -74,22 +73,8 @@ func NewNamespacedCustomResourceClient(ns string, client dynamic.Interface, defi }, ns) } -func NewNamespacedCustomResourceStatusClient(ns string, client dynamic.Interface, definition *apiextensionsv1beta1.CustomResourceDefinition) dynamic.ResourceInterface { - return client.Resource(&metav1.APIResource{ - Name: definition.Spec.Names.Plural + "/status", - Namespaced: definition.Spec.Scope == apiextensionsv1beta1.NamespaceScoped, - }, ns) -} - -func NewNamespacedCustomResourceScaleClient(ns string, client dynamic.Interface, definition *apiextensionsv1beta1.CustomResourceDefinition) dynamic.ResourceInterface { - return client.Resource(&metav1.APIResource{ - Name: definition.Spec.Names.Plural + "/scale", - Namespaced: definition.Spec.Scope == apiextensionsv1beta1.NamespaceScoped, - }, ns) -} - func TestMultipleResourceInstances(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -213,7 +198,7 @@ func TestMultipleResourceInstances(t *testing.T) { } func TestMultipleRegistration(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -269,7 +254,7 @@ func TestMultipleRegistration(t *testing.T) { } func TestDeRegistrationAndReRegistration(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -362,18 +347,12 @@ func TestEtcdStorage(t *testing.T) { if err != nil { t.Fatal(err) } - stopCh, clientConfig, err := testserver.StartServer(config) + stopCh, apiExtensionClient, clientPool, err := testserver.StartServer(config) if err != nil { t.Fatal(err) } defer close(stopCh) - apiExtensionClient, err := apiextensionsclientset.NewForConfig(clientConfig) - if err != nil { - t.Fatal(err) - } - clientPool := dynamic.NewDynamicClientPool(clientConfig) - etcdPrefix := getPrefixFromConfig(t, config) ns1 := "another-default-is-possible" diff --git a/vendor/k8s.io/apiextensions-apiserver/test/integration/subresources_test.go b/vendor/k8s.io/apiextensions-apiserver/test/integration/subresources_test.go deleted file mode 100644 index 7f04c8215..000000000 --- a/vendor/k8s.io/apiextensions-apiserver/test/integration/subresources_test.go +++ /dev/null @@ -1,787 +0,0 @@ -/* -Copyright 2018 The Kubernetes 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 integration - -import ( - "math" - "reflect" - "sort" - "strings" - "testing" - "time" - - autoscaling "k8s.io/api/autoscaling/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/wait" - utilfeature "k8s.io/apiserver/pkg/util/feature" - utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing" - "k8s.io/client-go/dynamic" - - apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" - "k8s.io/apiextensions-apiserver/pkg/features" - "k8s.io/apiextensions-apiserver/test/integration/testserver" -) - -var labelSelectorPath = ".status.labelSelector" - -func NewNoxuSubresourcesCRD(scope apiextensionsv1beta1.ResourceScope) *apiextensionsv1beta1.CustomResourceDefinition { - return &apiextensionsv1beta1.CustomResourceDefinition{ - ObjectMeta: metav1.ObjectMeta{Name: "noxus.mygroup.example.com"}, - Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{ - Group: "mygroup.example.com", - Version: "v1beta1", - Names: apiextensionsv1beta1.CustomResourceDefinitionNames{ - Plural: "noxus", - Singular: "nonenglishnoxu", - Kind: "WishIHadChosenNoxu", - ShortNames: []string{"foo", "bar", "abc", "def"}, - ListKind: "NoxuItemList", - }, - Scope: scope, - Subresources: &apiextensionsv1beta1.CustomResourceSubresources{ - Status: &apiextensionsv1beta1.CustomResourceSubresourceStatus{}, - Scale: &apiextensionsv1beta1.CustomResourceSubresourceScale{ - SpecReplicasPath: ".spec.replicas", - StatusReplicasPath: ".status.replicas", - LabelSelectorPath: &labelSelectorPath, - }, - }, - }, - } -} - -func NewNoxuSubresourceInstance(namespace, name string) *unstructured.Unstructured { - return &unstructured.Unstructured{ - Object: map[string]interface{}{ - "apiVersion": "mygroup.example.com/v1beta1", - "kind": "WishIHadChosenNoxu", - "metadata": map[string]interface{}{ - "namespace": namespace, - "name": name, - }, - "spec": map[string]interface{}{ - "num": int64(10), - "replicas": int64(3), - }, - "status": map[string]interface{}{ - "replicas": int64(7), - }, - }, - } -} - -func TestStatusSubresource(t *testing.T) { - // enable alpha feature CustomResourceSubresources - defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CustomResourceSubresources, true)() - - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() - if err != nil { - t.Fatal(err) - } - defer close(stopCh) - - noxuDefinition := NewNoxuSubresourcesCRD(apiextensionsv1beta1.NamespaceScoped) - noxuVersionClient, err := testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, clientPool) - if err != nil { - t.Fatal(err) - } - - ns := "not-the-default" - noxuResourceClient := NewNamespacedCustomResourceClient(ns, noxuVersionClient, noxuDefinition) - noxuStatusResourceClient := NewNamespacedCustomResourceStatusClient(ns, noxuVersionClient, noxuDefinition) - _, err = instantiateCustomResource(t, NewNoxuSubresourceInstance(ns, "foo"), noxuResourceClient, noxuDefinition) - if err != nil { - t.Fatalf("unable to create noxu instance: %v", err) - } - - gottenNoxuInstance, err := noxuResourceClient.Get("foo", metav1.GetOptions{}) - if err != nil { - t.Fatal(err) - } - - // status should not be set after creation - if val, ok := gottenNoxuInstance.Object["status"]; ok { - t.Fatalf("status should not be set after creation, got %v", val) - } - - // .status.num = 20 - err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(20), "status", "num") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // .spec.num = 20 - err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(20), "spec", "num") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // UpdateStatus should not update spec. - // Check that .spec.num = 10 and .status.num = 20 - updatedStatusInstance, err := noxuStatusResourceClient.Update(gottenNoxuInstance) - if err != nil { - t.Fatalf("unable to update status: %v", err) - } - - specNum, found, err := unstructured.NestedInt64(updatedStatusInstance.Object, "spec", "num") - if !found || err != nil { - t.Fatalf("unable to get .spec.num") - } - if specNum != int64(10) { - t.Fatalf(".spec.num: expected: %v, got: %v", int64(10), specNum) - } - - statusNum, found, err := unstructured.NestedInt64(updatedStatusInstance.Object, "status", "num") - if !found || err != nil { - t.Fatalf("unable to get .status.num") - } - if statusNum != int64(20) { - t.Fatalf(".status.num: expected: %v, got: %v", int64(20), statusNum) - } - - gottenNoxuInstance, err = noxuResourceClient.Get("foo", metav1.GetOptions{}) - if err != nil { - t.Fatal(err) - } - - // .status.num = 40 - err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(40), "status", "num") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // .spec.num = 40 - err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(40), "spec", "num") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // Update should not update status. - // Check that .spec.num = 40 and .status.num = 20 - updatedInstance, err := noxuResourceClient.Update(gottenNoxuInstance) - if err != nil { - t.Fatalf("unable to update instance: %v", err) - } - - specNum, found, err = unstructured.NestedInt64(updatedInstance.Object, "spec", "num") - if !found || err != nil { - t.Fatalf("unable to get .spec.num") - } - if specNum != int64(40) { - t.Fatalf(".spec.num: expected: %v, got: %v", int64(40), specNum) - } - - statusNum, found, err = unstructured.NestedInt64(updatedInstance.Object, "status", "num") - if !found || err != nil { - t.Fatalf("unable to get .status.num") - } - if statusNum != int64(20) { - t.Fatalf(".status.num: expected: %v, got: %v", int64(20), statusNum) - } -} - -func TestScaleSubresource(t *testing.T) { - // enable alpha feature CustomResourceSubresources - defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CustomResourceSubresources, true)() - - groupResource := schema.GroupResource{ - Group: "mygroup.example.com", - Resource: "noxus", - } - - stopCh, config, err := testserver.StartDefaultServer() - if err != nil { - t.Fatal(err) - } - defer close(stopCh) - - apiExtensionClient, err := clientset.NewForConfig(config) - if err != nil { - t.Fatal(err) - } - clientPool := dynamic.NewDynamicClientPool(config) - - noxuDefinition := NewNoxuSubresourcesCRD(apiextensionsv1beta1.NamespaceScoped) - - // set invalid json path for specReplicasPath - noxuDefinition.Spec.Subresources.Scale.SpecReplicasPath = "foo,bar" - _, err = testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, clientPool) - if err == nil { - t.Fatalf("unexpected non-error: specReplicasPath should be a valid json path under .spec") - } - - noxuDefinition.Spec.Subresources.Scale.SpecReplicasPath = ".spec.replicas" - noxuVersionClient, err := testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, clientPool) - if err != nil { - t.Fatal(err) - } - - ns := "not-the-default" - noxuResourceClient := NewNamespacedCustomResourceClient(ns, noxuVersionClient, noxuDefinition) - noxuStatusResourceClient := NewNamespacedCustomResourceStatusClient(ns, noxuVersionClient, noxuDefinition) - _, err = instantiateCustomResource(t, NewNoxuSubresourceInstance(ns, "foo"), noxuResourceClient, noxuDefinition) - if err != nil { - t.Fatalf("unable to create noxu instance: %v", err) - } - - scaleClient, err := testserver.CreateNewScaleClient(noxuDefinition, config) - if err != nil { - t.Fatal(err) - } - - // set .status.labelSelector = bar - gottenNoxuInstance, err := noxuResourceClient.Get("foo", metav1.GetOptions{}) - if err != nil { - t.Fatal(err) - } - err = unstructured.SetNestedField(gottenNoxuInstance.Object, "bar", "status", "labelSelector") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - _, err = noxuStatusResourceClient.Update(gottenNoxuInstance) - if err != nil { - t.Fatalf("unable to update status: %v", err) - } - - // get the scale object - gottenScale, err := scaleClient.Scales("not-the-default").Get(groupResource, "foo") - if err != nil { - t.Fatal(err) - } - if gottenScale.Spec.Replicas != 3 { - t.Fatalf("Scale.Spec.Replicas: expected: %v, got: %v", 3, gottenScale.Spec.Replicas) - } - if gottenScale.Status.Selector != "bar" { - t.Fatalf("Scale.Status.Selector: expected: %v, got: %v", "bar", gottenScale.Status.Selector) - } - - // check self link - expectedSelfLink := "/apis/mygroup.example.com/v1beta1/namespaces/not-the-default/noxus/foo/scale" - if gottenScale.GetSelfLink() != expectedSelfLink { - t.Fatalf("Scale.Metadata.SelfLink: expected: %v, got: %v", expectedSelfLink, gottenScale.GetSelfLink()) - } - - // update the scale object - // check that spec is updated, but status is not - gottenScale.Spec.Replicas = 5 - gottenScale.Status.Selector = "baz" - updatedScale, err := scaleClient.Scales("not-the-default").Update(groupResource, gottenScale) - if err != nil { - t.Fatal(err) - } - if updatedScale.Spec.Replicas != 5 { - t.Fatalf("replicas: expected: %v, got: %v", 5, updatedScale.Spec.Replicas) - } - if updatedScale.Status.Selector != "bar" { - t.Fatalf("scale should not update status: expected %v, got: %v", "bar", updatedScale.Status.Selector) - } - - // check that .spec.replicas = 5, but status is not updated - updatedNoxuInstance, err := noxuResourceClient.Get("foo", metav1.GetOptions{}) - if err != nil { - t.Fatal(err) - } - specReplicas, found, err := unstructured.NestedInt64(updatedNoxuInstance.Object, "spec", "replicas") - if !found || err != nil { - t.Fatalf("unable to get .spec.replicas") - } - if specReplicas != 5 { - t.Fatalf("replicas: expected: %v, got: %v", 5, specReplicas) - } - statusLabelSelector, found, err := unstructured.NestedString(updatedNoxuInstance.Object, "status", "labelSelector") - if !found || err != nil { - t.Fatalf("unable to get .status.labelSelector") - } - if statusLabelSelector != "bar" { - t.Fatalf("scale should not update status: expected %v, got: %v", "bar", statusLabelSelector) - } - - // validate maximum value - // set .spec.replicas = math.MaxInt64 - gottenNoxuInstance, err = noxuResourceClient.Get("foo", metav1.GetOptions{}) - if err != nil { - t.Fatal(err) - } - err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(math.MaxInt64), "spec", "replicas") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - _, err = noxuResourceClient.Update(gottenNoxuInstance) - if err == nil { - t.Fatalf("unexpected non-error: .spec.replicas should be less than 2147483647") - } -} - -func TestValidationSchema(t *testing.T) { - // enable alpha feature CustomResourceSubresources - defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CustomResourceSubresources, true)() - - stopCh, config, err := testserver.StartDefaultServer() - if err != nil { - t.Fatal(err) - } - defer close(stopCh) - - apiExtensionClient, err := clientset.NewForConfig(config) - if err != nil { - t.Fatal(err) - } - clientPool := dynamic.NewDynamicClientPool(config) - - // fields other than properties in root schema are not allowed - noxuDefinition := newNoxuValidationCRD(apiextensionsv1beta1.NamespaceScoped) - _, err = testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, clientPool) - if err == nil { - t.Fatalf("unexpected non-error: if subresources for custom resources are enabled, only properties can be used at the root of the schema") - } - - // make sure we are not restricting fields to properties even in subschemas - noxuDefinition.Spec.Validation.OpenAPIV3Schema = &apiextensionsv1beta1.JSONSchemaProps{ - Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{ - "spec": { - Description: "Validation for spec", - Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{ - "replicas": { - Type: "integer", - }, - }, - }, - }, - } - _, err = testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, clientPool) - if err != nil { - t.Fatalf("unable to created crd %v: %v", noxuDefinition.Name, err) - } -} - -func TestValidateOnlyStatus(t *testing.T) { - // enable alpha feature CustomResourceSubresources - defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CustomResourceSubresources, true)() - - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() - if err != nil { - t.Fatal(err) - } - defer close(stopCh) - - // UpdateStatus should validate only status - // 1. create a crd with max value of .spec.num = 10 and .status.num = 10 - // 2. create a cr with .spec.num = 10 and .status.num = 10 (valid) - // 3. update the crd so that max value of .spec.num = 5 and .status.num = 10 - // 4. update the status of the cr with .status.num = 5 (spec is invalid) - // validation passes becauses spec is not validated - - // max value of spec.num = 10 and status.num = 10 - schema := &apiextensionsv1beta1.JSONSchemaProps{ - Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{ - "spec": { - Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{ - "num": { - Type: "integer", - Maximum: float64Ptr(10), - }, - }, - }, - "status": { - Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{ - "num": { - Type: "integer", - Maximum: float64Ptr(10), - }, - }, - }, - }, - } - - noxuDefinition := NewNoxuSubresourcesCRD(apiextensionsv1beta1.NamespaceScoped) - noxuDefinition.Spec.Validation = &apiextensionsv1beta1.CustomResourceValidation{ - OpenAPIV3Schema: schema, - } - - noxuVersionClient, err := testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, clientPool) - if err != nil { - t.Fatal(err) - } - ns := "not-the-default" - noxuResourceClient := NewNamespacedCustomResourceClient(ns, noxuVersionClient, noxuDefinition) - noxuStatusResourceClient := NewNamespacedCustomResourceStatusClient(ns, noxuVersionClient, noxuDefinition) - - // set .spec.num = 10 and .status.num = 10 - noxuInstance := NewNoxuSubresourceInstance(ns, "foo") - err = unstructured.SetNestedField(noxuInstance.Object, int64(10), "status", "num") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - createdNoxuInstance, err := instantiateCustomResource(t, noxuInstance, noxuResourceClient, noxuDefinition) - if err != nil { - t.Fatalf("unable to create noxu instance: %v", err) - } - - gottenCRD, err := apiExtensionClient.ApiextensionsV1beta1().CustomResourceDefinitions().Get("noxus.mygroup.example.com", metav1.GetOptions{}) - if err != nil { - t.Fatal(err) - } - - // update the crd so that max value of spec.num = 5 and status.num = 10 - gottenCRD.Spec.Validation.OpenAPIV3Schema = &apiextensionsv1beta1.JSONSchemaProps{ - Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{ - "spec": { - Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{ - "num": { - Type: "integer", - Maximum: float64Ptr(5), - }, - }, - }, - "status": { - Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{ - "num": { - Type: "integer", - Maximum: float64Ptr(10), - }, - }, - }, - }, - } - - if _, err = apiExtensionClient.ApiextensionsV1beta1().CustomResourceDefinitions().Update(gottenCRD); err != nil { - t.Fatal(err) - } - - // update the status with .status.num = 5 - err = unstructured.SetNestedField(createdNoxuInstance.Object, int64(5), "status", "num") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // cr is updated even though spec is invalid - err = wait.Poll(500*time.Millisecond, wait.ForeverTestTimeout, func() (bool, error) { - _, err := noxuStatusResourceClient.Update(createdNoxuInstance) - if statusError, isStatus := err.(*apierrors.StatusError); isStatus { - if strings.Contains(statusError.Error(), "is invalid") { - return false, nil - } - } - if err != nil { - return false, err - } - return true, nil - }) - if err != nil { - t.Fatal(err) - } -} - -func TestSubresourcesDiscovery(t *testing.T) { - // enable alpha feature CustomResourceSubresources - defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CustomResourceSubresources, true)() - - stopCh, config, err := testserver.StartDefaultServer() - if err != nil { - t.Fatal(err) - } - defer close(stopCh) - - apiExtensionClient, err := clientset.NewForConfig(config) - if err != nil { - t.Fatal(err) - } - clientPool := dynamic.NewDynamicClientPool(config) - - noxuDefinition := NewNoxuSubresourcesCRD(apiextensionsv1beta1.NamespaceScoped) - _, err = testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, clientPool) - if err != nil { - t.Fatal(err) - } - - group := "mygroup.example.com" - version := "v1beta1" - - resources, err := apiExtensionClient.Discovery().ServerResourcesForGroupVersion(group + "/" + version) - if err != nil { - t.Fatal(err) - } - - if len(resources.APIResources) != 3 { - t.Fatalf("Expected exactly the resources \"noxus\", \"noxus/status\" and \"noxus/scale\" in group version %v/%v via discovery, got: %v", group, version, resources.APIResources) - } - - // check discovery info for status - status := resources.APIResources[1] - - if status.Name != "noxus/status" { - t.Fatalf("incorrect status via discovery: expected name: %v, got: %v", "noxus/status", status.Name) - } - - if status.Namespaced != true { - t.Fatalf("incorrect status via discovery: expected namespace: %v, got: %v", true, status.Namespaced) - } - - if status.Kind != "WishIHadChosenNoxu" { - t.Fatalf("incorrect status via discovery: expected kind: %v, got: %v", "WishIHadChosenNoxu", status.Kind) - } - - expectedVerbs := []string{"get", "patch", "update"} - sort.Strings(status.Verbs) - if !reflect.DeepEqual([]string(status.Verbs), expectedVerbs) { - t.Fatalf("incorrect status via discovery: expected: %v, got: %v", expectedVerbs, status.Verbs) - } - - // check discovery info for scale - scale := resources.APIResources[2] - - if scale.Group != autoscaling.GroupName { - t.Fatalf("incorrect scale via discovery: expected group: %v, got: %v", autoscaling.GroupName, scale.Group) - } - - if scale.Version != "v1" { - t.Fatalf("incorrect scale via discovery: expected version: %v, got %v", "v1", scale.Version) - } - - if scale.Name != "noxus/scale" { - t.Fatalf("incorrect scale via discovery: expected name: %v, got: %v", "noxus/scale", scale.Name) - } - - if scale.Namespaced != true { - t.Fatalf("incorrect scale via discovery: expected namespace: %v, got: %v", true, scale.Namespaced) - } - - if scale.Kind != "Scale" { - t.Fatalf("incorrect scale via discovery: expected kind: %v, got: %v", "Scale", scale.Kind) - } - - sort.Strings(scale.Verbs) - if !reflect.DeepEqual([]string(scale.Verbs), expectedVerbs) { - t.Fatalf("incorrect scale via discovery: expected: %v, got: %v", expectedVerbs, scale.Verbs) - } -} - -func TestGeneration(t *testing.T) { - // enable alpha feature CustomResourceSubresources - defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CustomResourceSubresources, true)() - - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() - if err != nil { - t.Fatal(err) - } - defer close(stopCh) - - noxuDefinition := NewNoxuSubresourcesCRD(apiextensionsv1beta1.NamespaceScoped) - noxuVersionClient, err := testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, clientPool) - if err != nil { - t.Fatal(err) - } - - ns := "not-the-default" - noxuResourceClient := NewNamespacedCustomResourceClient(ns, noxuVersionClient, noxuDefinition) - noxuStatusResourceClient := NewNamespacedCustomResourceStatusClient(ns, noxuVersionClient, noxuDefinition) - _, err = instantiateCustomResource(t, NewNoxuSubresourceInstance(ns, "foo"), noxuResourceClient, noxuDefinition) - if err != nil { - t.Fatalf("unable to create noxu instance: %v", err) - } - - // .metadata.generation = 1 - gottenNoxuInstance, err := noxuResourceClient.Get("foo", metav1.GetOptions{}) - if err != nil { - t.Fatal(err) - } - if gottenNoxuInstance.GetGeneration() != 1 { - t.Fatalf(".metadata.generation should be 1 after creation") - } - - // .status.num = 20 - err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(20), "status", "num") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // UpdateStatus does not increment generation - updatedStatusInstance, err := noxuStatusResourceClient.Update(gottenNoxuInstance) - if err != nil { - t.Fatalf("unable to update status: %v", err) - } - if updatedStatusInstance.GetGeneration() != 1 { - t.Fatalf("updating status should not increment .metadata.generation: expected: %v, got: %v", 1, updatedStatusInstance.GetGeneration()) - } - - gottenNoxuInstance, err = noxuResourceClient.Get("foo", metav1.GetOptions{}) - if err != nil { - t.Fatal(err) - } - - // .spec.num = 20 - err = unstructured.SetNestedField(gottenNoxuInstance.Object, int64(20), "spec", "num") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // Update increments generation - updatedInstance, err := noxuResourceClient.Update(gottenNoxuInstance) - if err != nil { - t.Fatalf("unable to update instance: %v", err) - } - if updatedInstance.GetGeneration() != 2 { - t.Fatalf("updating spec should increment .metadata.generation: expected: %v, got: %v", 2, updatedStatusInstance.GetGeneration()) - } -} - -func TestSubresourcePatch(t *testing.T) { - // enable alpha feature CustomResourceSubresources - defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CustomResourceSubresources, true)() - - groupResource := schema.GroupResource{ - Group: "mygroup.example.com", - Resource: "noxus", - } - - stopCh, config, err := testserver.StartDefaultServer() - if err != nil { - t.Fatal(err) - } - defer close(stopCh) - - apiExtensionClient, err := clientset.NewForConfig(config) - if err != nil { - t.Fatal(err) - } - clientPool := dynamic.NewDynamicClientPool(config) - - noxuDefinition := NewNoxuSubresourcesCRD(apiextensionsv1beta1.NamespaceScoped) - noxuVersionClient, err := testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, clientPool) - if err != nil { - t.Fatal(err) - } - - ns := "not-the-default" - noxuResourceClient := NewNamespacedCustomResourceClient(ns, noxuVersionClient, noxuDefinition) - noxuStatusResourceClient := NewNamespacedCustomResourceStatusClient(ns, noxuVersionClient, noxuDefinition) - noxuScaleResourceClient := NewNamespacedCustomResourceScaleClient(ns, noxuVersionClient, noxuDefinition) - _, err = instantiateCustomResource(t, NewNoxuSubresourceInstance(ns, "foo"), noxuResourceClient, noxuDefinition) - if err != nil { - t.Fatalf("unable to create noxu instance: %v", err) - } - - scaleClient, err := testserver.CreateNewScaleClient(noxuDefinition, config) - if err != nil { - t.Fatal(err) - } - - patch := []byte(`{"spec": {"num":999}, "status": {"num":999}}`) - patchedNoxuInstance, err := noxuStatusResourceClient.Patch("foo", types.MergePatchType, patch) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // .spec.num should remain 10 - specNum, found, err := unstructured.NestedInt64(patchedNoxuInstance.Object, "spec", "num") - if !found || err != nil { - t.Fatalf("unable to get .spec.num") - } - if specNum != 10 { - t.Fatalf(".spec.num: expected: %v, got: %v", 10, specNum) - } - - // .status.num should be 999 - statusNum, found, err := unstructured.NestedInt64(patchedNoxuInstance.Object, "status", "num") - if !found || err != nil { - t.Fatalf("unable to get .status.num") - } - if statusNum != 999 { - t.Fatalf(".status.num: expected: %v, got: %v", 999, statusNum) - } - - // this call waits for the resourceVersion to be reached in the cache before returning. - // We need to do this because the patch gets its initial object from the storage, and the cache serves that. - // If it is out of date, then our initial patch is applied to an old resource version, which conflicts - // and then the updated object shows a conflicting diff, which permanently fails the patch. - // This gives expected stability in the patch without retrying on an known number of conflicts below in the test. - // See https://issue.k8s.io/42644 - _, err = noxuResourceClient.Get("foo", metav1.GetOptions{ResourceVersion: patchedNoxuInstance.GetResourceVersion()}) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // no-op patch - _, err = noxuStatusResourceClient.Patch("foo", types.MergePatchType, patch) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // empty patch - _, err = noxuStatusResourceClient.Patch("foo", types.MergePatchType, []byte(`{}`)) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - patch = []byte(`{"spec": {"replicas":7}, "status": {"replicas":7}}`) - patchedNoxuInstance, err = noxuScaleResourceClient.Patch("foo", types.MergePatchType, patch) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // this call waits for the resourceVersion to be reached in the cache before returning. - // We need to do this because the patch gets its initial object from the storage, and the cache serves that. - // If it is out of date, then our initial patch is applied to an old resource version, which conflicts - // and then the updated object shows a conflicting diff, which permanently fails the patch. - // This gives expected stability in the patch without retrying on an known number of conflicts below in the test. - // See https://issue.k8s.io/42644 - _, err = noxuResourceClient.Get("foo", metav1.GetOptions{ResourceVersion: patchedNoxuInstance.GetResourceVersion()}) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // Scale.Spec.Replicas = 7 but Scale.Status.Replicas should remain 7 - gottenScale, err := scaleClient.Scales("not-the-default").Get(groupResource, "foo") - if err != nil { - t.Fatal(err) - } - if gottenScale.Spec.Replicas != 7 { - t.Fatalf("Scale.Spec.Replicas: expected: %v, got: %v", 7, gottenScale.Spec.Replicas) - } - if gottenScale.Status.Replicas != 0 { - t.Fatalf("Scale.Status.Replicas: expected: %v, got: %v", 0, gottenScale.Spec.Replicas) - } - - // no-op patch - _, err = noxuScaleResourceClient.Patch("foo", types.MergePatchType, patch) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // empty patch - _, err = noxuScaleResourceClient.Patch("foo", types.MergePatchType, []byte(`{}`)) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - // make sure strategic merge patch is not supported for both status and scale - _, err = noxuStatusResourceClient.Patch("foo", types.StrategicMergePatchType, patch) - if err == nil { - t.Fatalf("unexpected non-error: strategic merge patch is not supported for custom resources") - } - - _, err = noxuScaleResourceClient.Patch("foo", types.StrategicMergePatchType, patch) - if err == nil { - t.Fatalf("unexpected non-error: strategic merge patch is not supported for custom resources") - } -} diff --git a/vendor/k8s.io/apiextensions-apiserver/test/integration/testserver/BUILD b/vendor/k8s.io/apiextensions-apiserver/test/integration/testserver/BUILD index 8c12d58d3..ae2ae0efe 100644 --- a/vendor/k8s.io/apiextensions-apiserver/test/integration/testserver/BUILD +++ b/vendor/k8s.io/apiextensions-apiserver/test/integration/testserver/BUILD @@ -26,12 +26,8 @@ go_library( "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//vendor/k8s.io/apimachinery/pkg/watch:go_default_library", "//vendor/k8s.io/apiserver/pkg/server:go_default_library", - "//vendor/k8s.io/apiserver/pkg/server/options:go_default_library", "//vendor/k8s.io/apiserver/pkg/storage/names:go_default_library", - "//vendor/k8s.io/client-go/discovery:go_default_library", "//vendor/k8s.io/client-go/dynamic:go_default_library", - "//vendor/k8s.io/client-go/rest:go_default_library", - "//vendor/k8s.io/client-go/scale:go_default_library", ], ) diff --git a/vendor/k8s.io/apiextensions-apiserver/test/integration/testserver/resources.go b/vendor/k8s.io/apiextensions-apiserver/test/integration/testserver/resources.go index bf54e1490..562281f4c 100644 --- a/vendor/k8s.io/apiextensions-apiserver/test/integration/testserver/resources.go +++ b/vendor/k8s.io/apiextensions-apiserver/test/integration/testserver/resources.go @@ -30,10 +30,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/watch" "k8s.io/apiserver/pkg/storage/names" - "k8s.io/client-go/discovery" "k8s.io/client-go/dynamic" - "k8s.io/client-go/rest" - "k8s.io/client-go/scale" ) const ( @@ -72,7 +69,6 @@ func NewNoxuCustomResourceDefinition(scope apiextensionsv1beta1.ResourceScope) * Kind: "WishIHadChosenNoxu", ShortNames: []string{"foo", "bar", "abc", "def"}, ListKind: "NoxuItemList", - Categories: []string{"all"}, }, Scope: scope, }, @@ -297,34 +293,3 @@ func DeleteCustomResourceDefinition(crd *apiextensionsv1beta1.CustomResourceDefi func GetCustomResourceDefinition(crd *apiextensionsv1beta1.CustomResourceDefinition, apiExtensionsClient clientset.Interface) (*apiextensionsv1beta1.CustomResourceDefinition, error) { return apiExtensionsClient.Apiextensions().CustomResourceDefinitions().Get(crd.Name, metav1.GetOptions{}) } - -func CreateNewScaleClient(crd *apiextensionsv1beta1.CustomResourceDefinition, config *rest.Config) (scale.ScalesGetter, error) { - discoveryClient, err := discovery.NewDiscoveryClientForConfig(config) - if err != nil { - return nil, err - } - groupResource, err := discoveryClient.ServerResourcesForGroupVersion(crd.Spec.Group + "/" + crd.Spec.Version) - if err != nil { - return nil, err - } - - resources := []*discovery.APIGroupResources{ - { - Group: metav1.APIGroup{ - Name: crd.Spec.Group, - Versions: []metav1.GroupVersionForDiscovery{ - {Version: crd.Spec.Version}, - }, - PreferredVersion: metav1.GroupVersionForDiscovery{Version: crd.Spec.Version}, - }, - VersionedResources: map[string][]metav1.APIResource{ - crd.Spec.Version: groupResource.APIResources, - }, - }, - } - - restMapper := discovery.NewRESTMapper(resources, nil) - resolver := scale.NewDiscoveryScaleKindResolver(discoveryClient) - - return scale.NewForConfig(config, restMapper, dynamic.LegacyAPIPathResolverFunc, resolver) -} diff --git a/vendor/k8s.io/apiextensions-apiserver/test/integration/testserver/start.go b/vendor/k8s.io/apiextensions-apiserver/test/integration/testserver/start.go index c0a60bfc7..99cbe9b3f 100644 --- a/vendor/k8s.io/apiextensions-apiserver/test/integration/testserver/start.go +++ b/vendor/k8s.io/apiextensions-apiserver/test/integration/testserver/start.go @@ -20,6 +20,7 @@ import ( "fmt" "net" "os" + "strconv" "time" "github.com/pborman/uuid" @@ -30,13 +31,11 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/util/wait" genericapiserver "k8s.io/apiserver/pkg/server" - genericapiserveroptions "k8s.io/apiserver/pkg/server/options" "k8s.io/client-go/dynamic" - "k8s.io/client-go/rest" ) func DefaultServerConfig() (*extensionsapiserver.Config, error) { - listener, port, err := genericapiserveroptions.CreateListener("tcp", "127.0.0.1:0") + port, err := FindFreeLocalPort() if err != nil { return nil, err } @@ -46,9 +45,7 @@ func DefaultServerConfig() (*extensionsapiserver.Config, error) { options.RecommendedOptions.SecureServing.BindPort = port options.RecommendedOptions.Authentication = nil // disable options.RecommendedOptions.Authorization = nil // disable - options.RecommendedOptions.Admission = nil // disable options.RecommendedOptions.SecureServing.BindAddress = net.ParseIP("127.0.0.1") - options.RecommendedOptions.SecureServing.Listener = listener etcdURL, ok := os.LookupEnv("KUBE_INTEGRATION_ETCD_URL") if !ok { etcdURL = "http://127.0.0.1:2379" @@ -61,10 +58,7 @@ func DefaultServerConfig() (*extensionsapiserver.Config, error) { if err := options.RecommendedOptions.SecureServing.MaybeDefaultWithSelfSignedCerts("localhost", nil, []net.IP{net.ParseIP("127.0.0.1")}); err != nil { return nil, fmt.Errorf("error creating self-signed certificates: %v", err) } - if err := options.RecommendedOptions.ApplyTo(genericConfig, nil); err != nil { - return nil, err - } - if err := options.APIEnablement.ApplyTo(&genericConfig.Config, extensionsapiserver.DefaultAPIResourceConfigSource(), extensionsapiserver.Registry); err != nil { + if err := options.RecommendedOptions.ApplyTo(genericConfig); err != nil { return nil, err } @@ -88,11 +82,11 @@ func DefaultServerConfig() (*extensionsapiserver.Config, error) { return config, nil } -func StartServer(config *extensionsapiserver.Config) (chan struct{}, *rest.Config, error) { +func StartServer(config *extensionsapiserver.Config) (chan struct{}, clientset.Interface, dynamic.ClientPool, error) { stopCh := make(chan struct{}) server, err := config.Complete().New(genericapiserver.EmptyDelegate) if err != nil { - return nil, nil, err + return nil, nil, nil, err } go func() { err := server.GenericAPIServer.PrepareRun().Run(stopCh) @@ -124,32 +118,48 @@ func StartServer(config *extensionsapiserver.Config) (chan struct{}, *rest.Confi }) if err != nil { close(stopCh) - return nil, nil, err - } - - return stopCh, config.GenericConfig.LoopbackClientConfig, nil -} - -func StartDefaultServer() (chan struct{}, *rest.Config, error) { - config, err := DefaultServerConfig() - if err != nil { - return nil, nil, err - } - - return StartServer(config) -} - -func StartDefaultServerWithClients() (chan struct{}, clientset.Interface, dynamic.ClientPool, error) { - stopCh, config, err := StartDefaultServer() - if err != nil { return nil, nil, nil, err } - apiExtensionsClient, err := clientset.NewForConfig(config) + apiExtensionsClient, err := clientset.NewForConfig(server.GenericAPIServer.LoopbackClientConfig) if err != nil { close(stopCh) return nil, nil, nil, err } - return stopCh, apiExtensionsClient, dynamic.NewDynamicClientPool(config), nil + bytes, _ := apiExtensionsClient.Discovery().RESTClient().Get().AbsPath("/apis/apiextensions.k8s.io/v1beta1").DoRaw() + fmt.Print(string(bytes)) + + return stopCh, apiExtensionsClient, dynamic.NewDynamicClientPool(server.GenericAPIServer.LoopbackClientConfig), nil +} + +func StartDefaultServer() (chan struct{}, clientset.Interface, dynamic.ClientPool, error) { + config, err := DefaultServerConfig() + if err != nil { + return nil, nil, nil, err + } + + return StartServer(config) +} + +// FindFreeLocalPort returns the number of an available port number on +// the loopback interface. Useful for determining the port to launch +// a server on. Error handling required - there is a non-zero chance +// that the returned port number will be bound by another process +// after this function returns. +func FindFreeLocalPort() (int, error) { + l, err := net.Listen("tcp", ":0") + if err != nil { + return 0, err + } + defer l.Close() + _, portStr, err := net.SplitHostPort(l.Addr().String()) + if err != nil { + return 0, err + } + port, err := strconv.Atoi(portStr) + if err != nil { + return 0, err + } + return port, nil } diff --git a/vendor/k8s.io/apiextensions-apiserver/test/integration/validation_test.go b/vendor/k8s.io/apiextensions-apiserver/test/integration/validation_test.go index 3ef47b658..2538149e2 100644 --- a/vendor/k8s.io/apiextensions-apiserver/test/integration/validation_test.go +++ b/vendor/k8s.io/apiextensions-apiserver/test/integration/validation_test.go @@ -31,7 +31,7 @@ import ( ) func TestForProperValidationErrors(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -169,7 +169,7 @@ func newNoxuValidationInstance(namespace, name string) *unstructured.Unstructure } func TestCustomResourceValidation(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -190,7 +190,7 @@ func TestCustomResourceValidation(t *testing.T) { } func TestCustomResourceUpdateValidation(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -233,7 +233,7 @@ func TestCustomResourceUpdateValidation(t *testing.T) { } func TestCustomResourceValidationErrors(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -324,7 +324,7 @@ func TestCustomResourceValidationErrors(t *testing.T) { } func TestCRValidationOnCRDUpdate(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -378,7 +378,7 @@ func TestCRValidationOnCRDUpdate(t *testing.T) { } func TestForbiddenFieldsInSchema(t *testing.T) { - stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServerWithClients() + stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } @@ -403,23 +403,16 @@ func TestForbiddenFieldsInSchema(t *testing.T) { t.Fatalf("unexpected non-error: uniqueItems cannot be set to true") } - noxuDefinition.Spec.Validation.OpenAPIV3Schema.Ref = strPtr("#/definition/zeta") noxuDefinition.Spec.Validation.OpenAPIV3Schema.Properties["zeta"] = apiextensionsv1beta1.JSONSchemaProps{ Type: "array", UniqueItems: false, } - _, err = testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, clientPool) - if err == nil { - t.Fatal("unexpected non-error: $ref cannot be non-empty string") - } - - noxuDefinition.Spec.Validation.OpenAPIV3Schema.Ref = nil - _, err = testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, clientPool) if err != nil { t.Fatal(err) } + } func float64Ptr(f float64) *float64 { @@ -429,7 +422,3 @@ func float64Ptr(f float64) *float64 { func int64Ptr(f int64) *int64 { return &f } - -func strPtr(str string) *string { - return &str -} diff --git a/vendor/k8s.io/apiextensions-apiserver/test/integration/yaml_test.go b/vendor/k8s.io/apiextensions-apiserver/test/integration/yaml_test.go deleted file mode 100644 index 9f23427f0..000000000 --- a/vendor/k8s.io/apiextensions-apiserver/test/integration/yaml_test.go +++ /dev/null @@ -1,541 +0,0 @@ -/* -Copyright 2018 The Kubernetes 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 integration - -import ( - "encoding/json" - "fmt" - "net/http" - "testing" - - "github.com/ghodss/yaml" - - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/types" - utilfeature "k8s.io/apiserver/pkg/util/feature" - utilfeaturetesting "k8s.io/apiserver/pkg/util/feature/testing" - "k8s.io/client-go/dynamic" - - apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" - "k8s.io/apiextensions-apiserver/pkg/features" - "k8s.io/apiextensions-apiserver/test/integration/testserver" -) - -func TestYAML(t *testing.T) { - stopCh, config, err := testserver.StartDefaultServer() - if err != nil { - t.Fatal(err) - } - defer close(stopCh) - - apiExtensionClient, err := clientset.NewForConfig(config) - if err != nil { - t.Fatal(err) - } - clientPool := dynamic.NewDynamicClientPool(config) - - noxuDefinition := testserver.NewNoxuCustomResourceDefinition(apiextensionsv1beta1.ClusterScoped) - _, err = testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, clientPool) - if err != nil { - t.Fatal(err) - } - - kind := noxuDefinition.Spec.Names.Kind - listKind := noxuDefinition.Spec.Names.ListKind - apiVersion := noxuDefinition.Spec.Group + "/" + noxuDefinition.Spec.Version - - rest := apiExtensionClient.Discovery().RESTClient() - - // Discovery - { - result, err := rest.Get(). - SetHeader("Accept", "application/yaml"). - AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version). - DoRaw() - if err != nil { - t.Fatal(err, string(result)) - } - obj, err := decodeYAML(result) - if err != nil { - t.Fatal(err) - } - if obj.GetAPIVersion() != "v1" || obj.GetKind() != "APIResourceList" { - t.Fatalf("unexpected discovery kind: %s", string(result)) - } - if v, ok, err := unstructured.NestedString(obj.Object, "groupVersion"); v != apiVersion || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - } - - // Error - { - result, err := rest.Get(). - SetHeader("Accept", "application/yaml"). - AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version, noxuDefinition.Spec.Names.Plural, "missingname"). - DoRaw() - if !errors.IsNotFound(err) { - t.Fatalf("expected not found, got %v", err) - } - obj, err := decodeYAML(result) - if err != nil { - t.Fatal(err) - } - if obj.GetAPIVersion() != "v1" || obj.GetKind() != "Status" { - t.Fatalf("unexpected discovery kind: %s", string(result)) - } - if v, ok, err := unstructured.NestedString(obj.Object, "reason"); v != "NotFound" || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - } - - uid := types.UID("") - resourceVersion := "" - - // Create - { - yamlBody := []byte(fmt.Sprintf(` -apiVersion: %s -kind: %s -metadata: - name: mytest -values: - numVal: 1 - boolVal: true - stringVal: "1"`, apiVersion, kind)) - - result, err := rest.Post(). - SetHeader("Accept", "application/yaml"). - SetHeader("Content-Type", "application/yaml"). - AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version, noxuDefinition.Spec.Names.Plural). - Body(yamlBody). - DoRaw() - if err != nil { - t.Fatal(err, string(result)) - } - obj, err := decodeYAML(result) - if err != nil { - t.Fatal(err) - } - if obj.GetName() != "mytest" { - t.Fatalf("expected mytest, got %s", obj.GetName()) - } - if obj.GetAPIVersion() != apiVersion { - t.Fatalf("expected %s, got %s", apiVersion, obj.GetAPIVersion()) - } - if obj.GetKind() != kind { - t.Fatalf("expected %s, got %s", kind, obj.GetKind()) - } - if v, ok, err := unstructured.NestedFloat64(obj.Object, "values", "numVal"); v != 1 || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - if v, ok, err := unstructured.NestedBool(obj.Object, "values", "boolVal"); v != true || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - if v, ok, err := unstructured.NestedString(obj.Object, "values", "stringVal"); v != "1" || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - uid = obj.GetUID() - resourceVersion = obj.GetResourceVersion() - } - - // Get - { - result, err := rest.Get(). - SetHeader("Accept", "application/yaml"). - AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version, noxuDefinition.Spec.Names.Plural, "mytest"). - DoRaw() - if err != nil { - t.Fatal(err) - } - obj, err := decodeYAML(result) - if err != nil { - t.Fatal(err, string(result)) - } - if obj.GetName() != "mytest" { - t.Fatalf("expected mytest, got %s", obj.GetName()) - } - if obj.GetAPIVersion() != apiVersion { - t.Fatalf("expected %s, got %s", apiVersion, obj.GetAPIVersion()) - } - if obj.GetKind() != kind { - t.Fatalf("expected %s, got %s", kind, obj.GetKind()) - } - if v, ok, err := unstructured.NestedFloat64(obj.Object, "values", "numVal"); v != 1 || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - if v, ok, err := unstructured.NestedBool(obj.Object, "values", "boolVal"); v != true || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - if v, ok, err := unstructured.NestedString(obj.Object, "values", "stringVal"); v != "1" || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - } - - // List - { - result, err := rest.Get(). - SetHeader("Accept", "application/yaml"). - AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version, noxuDefinition.Spec.Names.Plural). - DoRaw() - if err != nil { - t.Fatal(err, string(result)) - } - listObj, err := decodeYAML(result) - if err != nil { - t.Fatal(err) - } - if listObj.GetAPIVersion() != apiVersion { - t.Fatalf("expected %s, got %s", apiVersion, listObj.GetAPIVersion()) - } - if listObj.GetKind() != listKind { - t.Fatalf("expected %s, got %s", kind, listObj.GetKind()) - } - items, ok, err := unstructured.NestedSlice(listObj.Object, "items") - if !ok || err != nil || len(items) != 1 { - t.Fatalf("expected one item, got %v %v %v", items, ok, err) - } - obj := unstructured.Unstructured{Object: items[0].(map[string]interface{})} - if obj.GetName() != "mytest" { - t.Fatalf("expected mytest, got %s", obj.GetName()) - } - if obj.GetAPIVersion() != apiVersion { - t.Fatalf("expected %s, got %s", apiVersion, obj.GetAPIVersion()) - } - if obj.GetKind() != kind { - t.Fatalf("expected %s, got %s", kind, obj.GetKind()) - } - if v, ok, err := unstructured.NestedFloat64(obj.Object, "values", "numVal"); v != 1 || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - if v, ok, err := unstructured.NestedBool(obj.Object, "values", "boolVal"); v != true || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - if v, ok, err := unstructured.NestedString(obj.Object, "values", "stringVal"); v != "1" || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - } - - // Watch rejects yaml (no streaming support) - { - result, err := rest.Get(). - SetHeader("Accept", "application/yaml"). - AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version, noxuDefinition.Spec.Names.Plural). - Param("watch", "true"). - DoRaw() - if !errors.IsNotAcceptable(err) { - t.Fatalf("expected not acceptable error, got %v (%s)", err, string(result)) - } - obj, err := decodeYAML(result) - if err != nil { - t.Fatal(err) - } - if obj.GetAPIVersion() != "v1" || obj.GetKind() != "Status" { - t.Fatalf("unexpected result: %s", string(result)) - } - if v, ok, err := unstructured.NestedString(obj.Object, "reason"); v != "NotAcceptable" || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - if v, ok, err := unstructured.NestedFloat64(obj.Object, "code"); v != http.StatusNotAcceptable || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - } - - // Update - { - yamlBody := []byte(fmt.Sprintf(` -apiVersion: %s -kind: %s -metadata: - name: mytest - uid: %s - resourceVersion: "%s" -values: - numVal: 2 - boolVal: false - stringVal: "2"`, apiVersion, kind, uid, resourceVersion)) - result, err := rest.Put(). - SetHeader("Accept", "application/yaml"). - SetHeader("Content-Type", "application/yaml"). - AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version, noxuDefinition.Spec.Names.Plural, "mytest"). - Body(yamlBody). - DoRaw() - if err != nil { - t.Fatal(err, string(result)) - } - obj, err := decodeYAML(result) - if err != nil { - t.Fatal(err) - } - if obj.GetName() != "mytest" { - t.Fatalf("expected mytest, got %s", obj.GetName()) - } - if obj.GetAPIVersion() != apiVersion { - t.Fatalf("expected %s, got %s", apiVersion, obj.GetAPIVersion()) - } - if obj.GetKind() != kind { - t.Fatalf("expected %s, got %s", kind, obj.GetKind()) - } - if v, ok, err := unstructured.NestedFloat64(obj.Object, "values", "numVal"); v != 2 || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - if v, ok, err := unstructured.NestedBool(obj.Object, "values", "boolVal"); v != false || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - if v, ok, err := unstructured.NestedString(obj.Object, "values", "stringVal"); v != "2" || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - if obj.GetUID() != uid { - t.Fatalf("uid changed: %v vs %v", uid, obj.GetUID()) - } - } - - // Patch rejects yaml requests (only JSON mime types are allowed) - { - yamlBody := []byte(fmt.Sprintf(` -values: - numVal: 3`)) - result, err := rest.Patch(types.MergePatchType). - SetHeader("Accept", "application/yaml"). - SetHeader("Content-Type", "application/yaml"). - AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version, noxuDefinition.Spec.Names.Plural, "mytest"). - Body(yamlBody). - DoRaw() - if !errors.IsUnsupportedMediaType(err) { - t.Fatalf("Expected bad request, got %v\n%s", err, string(result)) - } - obj, err := decodeYAML(result) - if err != nil { - t.Fatal(err) - } - if obj.GetAPIVersion() != "v1" || obj.GetKind() != "Status" { - t.Fatalf("expected %s %s, got %s %s", "v1", "Status", obj.GetAPIVersion(), obj.GetKind()) - } - if v, ok, err := unstructured.NestedString(obj.Object, "reason"); v != "UnsupportedMediaType" || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - } - - // Delete - { - result, err := rest.Delete(). - SetHeader("Accept", "application/yaml"). - AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version, noxuDefinition.Spec.Names.Plural, "mytest"). - DoRaw() - if err != nil { - t.Fatal(err, string(result)) - } - obj, err := decodeYAML(result) - if err != nil { - t.Fatal(err) - } - if obj.GetAPIVersion() != "v1" || obj.GetKind() != "Status" { - t.Fatalf("unexpected response: %s", string(result)) - } - if v, ok, err := unstructured.NestedString(obj.Object, "status"); v != "Success" || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - } -} - -func TestYAMLSubresource(t *testing.T) { - // enable alpha feature CustomResourceSubresources - defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CustomResourceSubresources, true)() - - stopCh, config, err := testserver.StartDefaultServer() - if err != nil { - t.Fatal(err) - } - defer close(stopCh) - - apiExtensionClient, err := clientset.NewForConfig(config) - if err != nil { - t.Fatal(err) - } - clientPool := dynamic.NewDynamicClientPool(config) - - noxuDefinition := NewNoxuSubresourcesCRD(apiextensionsv1beta1.ClusterScoped) - _, err = testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, clientPool) - if err != nil { - t.Fatal(err) - } - - kind := noxuDefinition.Spec.Names.Kind - apiVersion := noxuDefinition.Spec.Group + "/" + noxuDefinition.Spec.Version - - rest := apiExtensionClient.Discovery().RESTClient() - - uid := types.UID("") - resourceVersion := "" - - // Create - { - yamlBody := []byte(fmt.Sprintf(` -apiVersion: %s -kind: %s -metadata: - name: mytest -spec: - replicas: 3`, apiVersion, kind)) - - result, err := rest.Post(). - SetHeader("Accept", "application/yaml"). - SetHeader("Content-Type", "application/yaml"). - AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version, noxuDefinition.Spec.Names.Plural). - Body(yamlBody). - DoRaw() - if err != nil { - t.Fatal(err, string(result)) - } - obj, err := decodeYAML(result) - if err != nil { - t.Fatal(err) - } - if obj.GetName() != "mytest" { - t.Fatalf("expected mytest, got %s", obj.GetName()) - } - if obj.GetAPIVersion() != apiVersion { - t.Fatalf("expected %s, got %s", apiVersion, obj.GetAPIVersion()) - } - if obj.GetKind() != kind { - t.Fatalf("expected %s, got %s", kind, obj.GetKind()) - } - if v, ok, err := unstructured.NestedFloat64(obj.Object, "spec", "replicas"); v != 3 || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - uid = obj.GetUID() - resourceVersion = obj.GetResourceVersion() - } - - // Get at /status - { - result, err := rest.Get(). - SetHeader("Accept", "application/yaml"). - AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version, noxuDefinition.Spec.Names.Plural, "mytest", "status"). - DoRaw() - if err != nil { - t.Fatal(err) - } - obj, err := decodeYAML(result) - if err != nil { - t.Fatal(err, string(result)) - } - if obj.GetName() != "mytest" { - t.Fatalf("expected mytest, got %s", obj.GetName()) - } - if obj.GetAPIVersion() != apiVersion { - t.Fatalf("expected %s, got %s", apiVersion, obj.GetAPIVersion()) - } - if obj.GetKind() != kind { - t.Fatalf("expected %s, got %s", kind, obj.GetKind()) - } - if v, ok, err := unstructured.NestedFloat64(obj.Object, "spec", "replicas"); v != 3 || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - } - - // Update at /status - { - yamlBody := []byte(fmt.Sprintf(` -apiVersion: %s -kind: %s -metadata: - name: mytest - uid: %s - resourceVersion: "%s" -spec: - replicas: 5 -status: - replicas: 3`, apiVersion, kind, uid, resourceVersion)) - result, err := rest.Put(). - SetHeader("Accept", "application/yaml"). - SetHeader("Content-Type", "application/yaml"). - AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version, noxuDefinition.Spec.Names.Plural, "mytest", "status"). - Body(yamlBody). - DoRaw() - if err != nil { - t.Fatal(err, string(result)) - } - obj, err := decodeYAML(result) - if err != nil { - t.Fatal(err) - } - if obj.GetName() != "mytest" { - t.Fatalf("expected mytest, got %s", obj.GetName()) - } - if obj.GetAPIVersion() != apiVersion { - t.Fatalf("expected %s, got %s", apiVersion, obj.GetAPIVersion()) - } - if obj.GetKind() != kind { - t.Fatalf("expected %s, got %s", kind, obj.GetKind()) - } - if v, ok, err := unstructured.NestedFloat64(obj.Object, "spec", "replicas"); v != 3 || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - if v, ok, err := unstructured.NestedFloat64(obj.Object, "status", "replicas"); v != 3 || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - if obj.GetUID() != uid { - t.Fatalf("uid changed: %v vs %v", uid, obj.GetUID()) - } - } - - // Get at /scale - { - result, err := rest.Get(). - SetHeader("Accept", "application/yaml"). - AbsPath("/apis", noxuDefinition.Spec.Group, noxuDefinition.Spec.Version, noxuDefinition.Spec.Names.Plural, "mytest", "scale"). - DoRaw() - if err != nil { - t.Fatal(err) - } - obj, err := decodeYAML(result) - if err != nil { - t.Fatal(err, string(result)) - } - if obj.GetName() != "mytest" { - t.Fatalf("expected mytest, got %s", obj.GetName()) - } - if obj.GetAPIVersion() != "autoscaling/v1" { - t.Fatalf("expected %s, got %s", apiVersion, obj.GetAPIVersion()) - } - if obj.GetKind() != "Scale" { - t.Fatalf("expected %s, got %s", kind, obj.GetKind()) - } - if v, ok, err := unstructured.NestedFloat64(obj.Object, "spec", "replicas"); v != 3 || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - if v, ok, err := unstructured.NestedFloat64(obj.Object, "status", "replicas"); v != 3 || !ok || err != nil { - t.Fatal(v, ok, err, string(result)) - } - } -} - -func decodeYAML(data []byte) (*unstructured.Unstructured, error) { - retval := &unstructured.Unstructured{Object: map[string]interface{}{}} - // ensure this isn't JSON - if json.Unmarshal(data, &retval.Object) == nil { - return nil, fmt.Errorf("data is JSON, not YAML: %s", string(data)) - } - // ensure it is YAML - retval.Object = map[string]interface{}{} - if err := yaml.Unmarshal(data, &retval.Object); err != nil { - return nil, fmt.Errorf("error decoding YAML: %v\noriginal YAML: %s", err, string(data)) - } - return retval, nil -}